Node.js получить расширение файла

211

Я создаю функцию загрузки файла в node.js с экспресс-3.

Я хотел бы получить расширение файла изображения. так что я могу переименовать файл, а затем добавить расширение файла к нему.

app.post('/upload', function(req, res, next) {
    var is = fs.createReadStream(req.files.upload.path),
        fileExt = '', // I want to get the extension of the image here
        os = fs.createWriteStream('public/images/users/' + req.session.adress + '.' + fileExt);
});

Как я могу получить расширение изображения в node.js?

georgesamper
источник
1
stackoverflow.com/questions/10431845/… повторить?
счет автомат
3
Разве это не вопрос о MIME-типах, я хочу расширение файла
georgesamper

Ответы:

474

Я считаю, что вы можете сделать следующее, чтобы получить расширение имени файла.

var path = require('path')

path.extname('index.html')
// returns
'.html'
Snowfish
источник
54
Только будьте осторожны, он будет захватывать только символы после последней точки, поэтому имена файлов вроде app.css.gzбудут только возвращаться, .gzа не возвращаться .css.gz, что может или не может быть тем, что вы хотите.
xentek
18
В таком случае просто используйтеfilename.split('.').pop();
Aamir Afridi
12
@AamirAfridi Это возвращает ту же строку только без ..
не определено
13
Попробуйте 'filename.css.gz'.split('.').slice(1).join('.')получить все расширения
Тревор
10
Как правило, расширение является последним. И когда мы ожидаем более одного, например, tar.gz. лучше проверить, существует ли он в конце концов или нет. используя регулярное выражение, например. "tar.gz $" или созданием функции, которая делает это. как проверить это с конца и вернуться назад и посмотреть, полностью ли это соответствует. и у вас будет эта функция, которая проверяет расширение. ЗАЧЕМ? потому что насчет файлов, таких как jone.lastTest.654654556.tar.gz здесь, ожидаемое расширение - tar.gz, но если вы примените какую-либо функцию, которая дает форму 1-й точки, она не будет работать, как вы можете видеть
Mohamed Allal
33

Обновить

Поскольку оригинальный ответ, extname () был добавлен в pathмодуль, см. Ответ Snowfish.

Оригинальный ответ:

Я использую эту функцию, чтобы получить расширение файла, потому что я не нашел способ сделать это более простым способом (но я думаю, что есть):

function getExtension(filename) {
    var ext = path.extname(filename||'').split('.');
    return ext[ext.length - 1];
}

Вы должны требовать «путь», чтобы использовать его.

другой метод, который не использует модуль пути:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}
dievardump
источник
4
Да, это работает. Просто подумал, что будет проще использовать узел. Это то, что я сделал:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
Georgesamper
6
Вы действительно должны использовать модуль path, как указано в ответе @ Snowfish, а не писать свой собственный. Дополнительная информация: nodejs.org/api/path.html#path_path_extname_p
xentek
а как насчет того, когда файлы не показывают расширения ??
старик
19
// you can send full url here
function getExtension(filename) {
    return filename.split('.').pop();
}

Если вы используете экспресс, добавьте следующую строку при настройке промежуточного программного обеспечения (bodyParser)

app.use(express.bodyParser({ keepExtensions: true}));
Kamrul
источник
12

Гораздо эффективнее использовать substr()метод вместо split()&pop()

Посмотрите на различия в производительности здесь: http://jsperf.com/remove-first-character-from-string

// returns: 'html'
var path = require('path');
path.extname('index.html').substr(1);

введите описание изображения здесь

Обновление август 2019 г. Как отметил @xentek в комментариях; substr()теперь считается устаревшей функцией ( документация MDN ). Вы можете использовать substring()вместо этого. Разница между substr()и substring()заключается в том, что второй аргумент substr()- это максимальная длина для возврата, в то время как второй аргумент substring()- это индекс, на котором нужно остановиться (без включения этого символа). Кроме того, substr()принимает отрицательные начальные позиции, которые будут использоваться в качестве смещения от конца строки, в то время substring()как нет.

magikMaker
источник
Теперь есть предупреждение, поскольку substrоно считается устаревшей функцией, и ее следует избегать, когда это возможно. Дополнительная информация по MDN
Core972,
При выполнении теста substr (1) вы также должны учитывать время, потраченное на path.extname
eugenekr
11

Это решение поддерживает строки запросов!

var Url = require('url');
var Path = require('path');

var url = 'http://i.imgur.com/Mvv4bx8.jpg?querystring=true';
var result = Path.extname(Url.parse(url).pathname); // '.jpg'
aleclarson
источник
6

Простое решение без необходимости в требовании, которое решает проблему многократного продления периода:

var filename = 'file.with.long.extension';
var ext = filename.substring(filename.indexOf('.')); 
//ext = '.with.long.extension'

Или, если вы не хотите, чтобы начальная точка:

var filename = 'file.with.long.extension';
var ext = filename.substring(filename.indexOf('.')+1); 
//ext = 'with.long.extension'

Убедитесь, что у файла тоже есть расширение.

smileham
источник
4

Я думаю, что отображение заголовка Content-Type в запросе также будет работать. Это будет работать даже в тех случаях, когда вы загружаете файл без расширения. (когда имя файла не имеет расширения в запросе)

Предположим, вы отправляете свои данные, используя HTTP POST:

POST /upload2 HTTP/1.1
Host: localhost:7098
Connection: keep-alive
Content-Length: 1047799
Accept: */*
Origin: http://localhost:63342
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,    like Gecko) Chrome/51.0.2704.106 Safari/537.36
Content-Type: multipart/form-data; boundary=----   WebKitFormBoundaryPDULZN8DYK3VppPp
Referer: http://localhost:63342/Admin/index.html? _ijt=3a6a054pasorvrljf8t8ea0j4h
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,az;q=0.6,tr;q=0.4
Request Payload
------WebKitFormBoundaryPDULZN8DYK3VppPp
Content-Disposition: form-data; name="image"; filename="blob"
Content-Type: image/png


------WebKitFormBoundaryPDULZN8DYK3VppPp--

Здесь name Content-Type header содержит тип mime данных. Отображение этого типа MIME на расширение даст вам расширение файла :).

Restify BodyParser преобразует этот заголовок в свойство с типом имени

File {
  domain: 
   Domain {
     domain: null,
     _events: { .... },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [ ... ] },
  _events: {},
  _eventsCount: 0,
  _maxListeners: undefined,
  size: 1047621,
  path: '/tmp/upload_2a4ac9ef22f7156180d369162ef08cb8',
  name: 'blob',
  **type: 'image/png'**,
  hash: null,
  lastModifiedDate: Wed Jul 20 2016 16:12:21 GMT+0300 (EEST),
  _writeStream: 
  WriteStream {
   ... },
     writable: true,
     domain: 
     Domain {
        ...
     },
      _events: {},
      _eventsCount: 0,
     _maxListeners: undefined,
     path: '/tmp/upload_2a4ac9ef22f7156180d369162ef08cb8',
     fd: null,
     flags: 'w',
     mode: 438,
     start: undefined,
     pos: undefined,
     bytesWritten: 1047621,
     closed: true } 
}

Вы можете использовать этот заголовок и выполнять сопоставление расширений (подстроку и т. Д.) Вручную, но для этого также есть готовые библиотеки. Ниже двух были лучшие результаты, когда я делал поиск Google

  • мим
  • мим-типы

и их использование также просто:

 app.post('/upload2', function (req, res) {
  console.log(mime.extension(req.files.image.type));
 }

приведенный выше фрагмент выведет png на консоль.

rozaydin
источник
2
var fileName = req.files.upload.name;

var arr = fileName.split('.');

var extension = arr[length-1];
Раджеш
источник
1
откуда берется переменная длины?
Ангел С. Морено
3
Попробуйте добавить объяснение к вашему ответу. Таким образом, ОП может действительно понять, что вы сделали и почему вы это сделали. Таким образом, ОП может учиться на вашем ответе, а не просто копировать / вставлять его.
Oldskool
1

path.extnameсделает свое дело в большинстве случаев. Тем не менее, он будет включать в себя все после последнего ., включая строку запроса и хеш-фрагмент запроса http:

var path = require('path')
var extname = path.extname('index.html?username=asdf')
// extname contains '.html?username=asdf'

В таких случаях вы захотите попробовать что-то вроде этого:

var regex = /[#\\?]/g; // regex of illegal extension characters
var extname = path.extname('index.html?username=asdf');
var endOfExt = extname.search(regex);
if (endOfExt > -1) {
    extname = extname.substring(0, endOfExt);
}
// extname contains '.html'

Обратите внимание, что расширения с несколькими периодами (например, .tar.gz) не будут работать вообще path.extname.

выкопанный
источник
0

Следующая функция разбивает строку и возвращает имя и расширение независимо от того, сколько точек в расширении. Возвращает пустую строку для расширения, если ее нет. Имена, начинающиеся с точек и / или пробелов, также работают.

function basext(name) {
  name = name.trim()
  const match = name.match(/^(\.+)/)
  let prefix = ''
  if (match) {
    prefix = match[0]
    name = name.replace(prefix, '')
  }
  const index = name.indexOf('.')
  const ext = name.substring(index + 1)
  const base = name.substring(0, index) || ext
  return [prefix + base, base === ext ? '' : ext]
}

const [base, ext] = basext('hello.txt')
Видар
источник
0

импортируем extname, чтобы вернуть расширение файла:

import { extname } from 'path';
extname(file.originalname);

где файл - это имя файла формы

Vitalves
источник
0

Вы можете использовать path.parse (путь) , например

const path = require('path');
const { ext } = path.parse('/home/user/dir/file.txt');
ns16
источник
0

Попробуй это

const path = require('path');

function getExt(str) {
  const basename = path.basename(str);
  const firstDot = basename.indexOf('.');
  const lastDot = basename.lastIndexOf('.');
  const extname = path.extname(basename).replace(/(\.[a-z0-9]+).*/i, '$1');

  if (firstDot === lastDot) {
    return extname;
  }

  return basename.slice(firstDot, lastDot) + extname;
}

// all are `.gz`
console.log(getExt('/home/charlike/bar/file.gz'));
console.log(getExt('/home/charlike/bar/file.gz~'));
console.log(getExt('/home/charlike/bar/file.gz+cdf2'));
console.log(getExt('/home/charlike/bar/file.gz?quz=zaz'));

// all are `.tar.gz`
console.log(getExt('/home/charlike/bar/file.tar.gz'));
console.log(getExt('/home/charlike/bar/file.tar.gz~'));
console.log(getExt('/home/charlike/bar/file.tar.gz+cdf2'));
console.log(getExt('/home/charlike/bar/file.tar.gz?quz=zaz'));
tunnckoCore
источник