Node.js отримати розширення файлу


209

Я створюю функцію завантаження файлу в 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?



3
Це не питання про типи mime, я хочу розширення файлу
georgesamper

Відповіді:


472

Я вважаю, що ви можете зробити наступне, щоб отримати розширення імені файлу.

var path = require('path')

path.extname('index.html')
// returns
'.html'

54
Будьте обережні, вони захоплюватимуть символи лише після останньої крапки, тому назви файлів на кшталт app.css.gzповертаються лише, .gzа не .css.gz, що може бути, а може і не бути тим, що ви хочете.
xentek

18
У такому випадку просто використовуйтеfilename.split('.').pop();
Аамір Африді

12
@AamirAfridi Повертає ту саму рядок просто без ..
визначено

13
Спробуйте 'filename.css.gz'.split('.').slice(1).join('.')отримати всі розширення
Тревор,

10
Взагалі розширення є останнім. І коли ми очікуємо більше одного, як, наприклад, tar.gz. краще перевірити, чи існує він зрештою чи ні. наприклад, використовуючи регулярний вираз. "tar.gz $" або шляхом створення функції, яка це робить. як-от перевірити це з кінця і повернутися назад і побачити, чи повністю відповідає. і у вас буде та функція, яка перевіряє розширення. ЧОМУ? адже що стосується таких файлів, як jone.lastTest.654654556.tar.gz очікується, розширення tar.gz, але якщо застосувати будь-яку функцію, яка дає форму 1-ї крапки, вона не працюватиме, як ви бачите
Мохамед Аллал

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);
}

4
Так, це працює. Просто подумав, що буде більш простий спосіб використання вузла. Ось що я зробив:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
georgesamper

6
Вам слід просто використовувати модуль шляху, як вказувала відповідь @ Snowfish, а не писати свій власний. Більше інформації: nodejs.org/api/path.html#path_path_extname_p
xentek

а що робити, коли файли не показують розширення ??
oldboy

19
// you can send full url here
function getExtension(filename) {
    return filename.split('.').pop();
}

Якщо ви використовуєте експрес, додайте наступний рядок під час налаштування проміжного програмного забезпечення (bodyParser)

app.use(express.bodyParser({ keepExtensions: true}));

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()це не відбувається.


Зараз існує попередження, оскільки 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'

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'

Переконайтесь, що перевірити, чи файл також має розширення.


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--

Тут заголовок Content-Type містить тип 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 до консолі.


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);

де файл - це ім'я файлу форми



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'));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.