Node.js获取文件扩展名


209

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



3
这不是关于mime类型的问题,我想要文件扩展名
georgesamper 2012年

Answers:


472

我相信您可以执行以下操作来获取文件名的扩展名。

var path = require('path')

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

54
请注意,它只会抓取最后一个点后的字符,因此like这样的文件名app.css.gz只会返回.gznot .css.gz,而不会,这可能是您想要的,也可能不是。
xentek

18
在这种情况下,只需使用filename.split('.').pop();
Aamir Afridi

12
@AamirAfridi返回相同的字符串,只是不带.
未定义的

13
尝试'filename.css.gz'.split('.').slice(1).join('.')获取所有扩展名
Trevor

10
通常,扩展名是最后一个。当我们期望更多的东西时,例如tar.gz。最好检查它是否最后存在。例如使用正则表达式。“ tar.gz $”或通过构建执行该功能的函数。就像从头开始检查并返回,看是否完全匹配。您将拥有检查扩展名的功能。为什么?因为像jone.lastTest.654654556.tar.gz 这里这样的文件的扩展名是tar.gz,但是如果您应用任何给出第一个点形式的功能,那么它将无法正常工作
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);
}

4
是的,行得通。只是认为使用节点会更简单。这就是我所做的:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
georgesamper 2012年

6
正如@Snowfish的答案所指出的,您实际上应该只使用path模块,而不要自己编写。更多信息:nodejs.org/api/path.html#path_path_extname_p
xentek

当文件不显示扩展名怎么办?
老男孩

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

如果您使用Express,请在配置中间件(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年8月 @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
长度变量从何而来?
Angel S. Moreno 2015年

3
尝试在答案中添加一些解释。这样,OP就能真正了解您的操作以及执行此操作的原因。这样,OP可以从您的答案中学习,而不仅仅是复制/粘贴它。
Oldskool 2015年

1

path.extname在大多数情况下会解决问题。但是,它将包括last之后的所有内容.,包括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

导入扩展名以返回扩展名文件:

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

其中file是表单的文件“名称”



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'));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.