我用express 3在node.js中创建了一个文件上传函数。

我想抓取图像的文件扩展名。所以我可以重命名文件,然后附加文件扩展名。

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中获得图像的扩展名?


当前回答

更新

由于原来的答案,extname()已添加到路径模块,请参阅Snowfish答案

最初的回答:

我使用这个函数来获得文件扩展名,因为我没有找到一种更简单的方法(但我认为有):

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

你必须要求'path'才能使用它。

另一个不使用path模块的方法:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}

其他回答

更新

由于原来的答案,extname()已添加到路径模块,请参阅Snowfish答案

最初的回答:

我使用这个函数来获得文件扩展名,因为我没有找到一种更简单的方法(但我认为有):

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

你必须要求'path'才能使用它。

另一个不使用path模块的方法:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}
const path = require('path');

function getExt(str) {
  const basename = path
    .basename(str)
    // Patch: for hidden files
    // Removes all dots at the beginning of a line
    .replace(/^(\.+)/i, '');

  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;
}
const files = [
  '/home/charlike/bar/.hidden.tar.gz~',     // ".tar.gz"
  '/home/charlike/bar/file.tar.gz~',        // ".tar.gz"
  '/home/charlike/bar/file.tar.gz+cdf2',    // ".tar.gz"
  '/home/charlike/bar/file.tar.gz?quz=zaz', // ".tar.gz"
];

const fileAndExt = files.map((file) => [ file, getExt(file) ]);

console.log(JSON.stringify(fileAndExt, null, 2));

我认为在请求中映射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头包含数据的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 } 
}

你可以使用这个头文件并手动进行扩展映射(子字符串等),但也有现成的库。下面两个是我做谷歌搜索时最重要的结果

mime mime类型

它们的用法也很简单:

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

上面的代码片段将把PNG打印到控制台。

例如,您可以使用path.parse(path)

const path = require('path');
const { ext } = path.parse('/home/user/dir/file.txt');

使用substr()方法比使用split() & pop()方法更有效

在这里看看性能差异:http://jsperf.com/remove-first-character-from-string

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

Update August 2019 As pointed out by @xentek in the comments; substr() is now considered a legacy function (MDN documentation). You can use substring() instead. The difference between substr() and substring() is that the second argument of substr() is the maximum length to return while the second argument of substring() is the index to stop at (without including that character). Also, substr() accepts negative start positions to be used as an offset from the end of the string while substring() does not.