简体   繁体   English

Node.js 获取文件扩展名

[英]Node.js get file extension

Im creating a file upload function in node.js with express 3.我正在使用 express 3 在 node.js 中创建文件上传 function。

I would like to grab the file extension of the image.我想获取图像的文件扩展名。 so i can rename the file and then append the file extension to it.所以我可以重命名文件,然后 append 文件扩展名。

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

How can i get the extension of the image in node.js?我如何获得node.js中图像的扩展名?

I believe you can do the following to get the extension of a file name.我相信您可以执行以下操作来获取文件名的扩展名。

var path = require('path')

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

If you would like to get all extensions in a file name (eg filename.css.gz => css.gz ), try this:如果您想获取文件名中的所有扩展名(例如filename.css.gz => css.gz ),请尝试以下操作:

const ext = 'filename.css.gz'
  .split('.')
  .filter(Boolean) // removes empty extensions (e.g. `filename...txt`)
  .slice(1)
  .join('.')

console.log(ext) // prints 'css.gz'

Update更新

Since the original answer, extname() has been added to the path module, see Snowfish answer由于原始答案, extname()已添加到path模块,请参阅雪鱼答案

Original answer:原答案:

I'm using this function to get a file extension, because I didn't find a way to do it in an easier way (but I think there is) :我正在使用这个函数来获取文件扩展名,因为我没有找到一种更简单的方法(但我认为有):

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

you must require 'path' to use it.您必须要求“路径”才能使用它。

another method which does not use the path module :另一种不使用路径模块的方法:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}
// you can send full url here
function getExtension(filename) {
    return filename.split('.').pop();
}

If you are using express please add the following line when configuring middleware (bodyParser)如果您使用 express,请在配置中间件(bodyParser)时添加以下行

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

It's a lot more efficient to use the substr() method instead of split() & pop()使用substr()方法而不是split() & pop()更有效

Have a look at the performance differences here: http://jsperf.com/remove-first-character-from-string看看这里的性能差异: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;正如@xentek 在评论中指出的那样, 2019 年 8 月更新 substr() is now considered a legacy function ( MDN documentation ). substr()现在被认为是一个遗留函数( MDN 文档)。 You can use substring() instead.您可以改用substring() 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). substr()substring()之间的区别在于 substr( substr()的第二个参数是要返回的最大长度,而substring()的第二个参数是要停止的索引(不包括该字符)。 Also, substr() accepts negative start positions to be used as an offset from the end of the string while substring() does not.此外, substr()接受负的起始位置作为从字符串末尾的偏移量,而substring()不接受。

This solution supports querystrings!此解决方案支持查询字符串!

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'

A simple solution without need for require which solves the multiple period extension problem:一个不需要 require 的简单解决方案,它解决了多期延长问题:

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

Or if you don't want the leading dot:或者,如果您不想要前导点:

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

Make sure to test that the file has an extension too.确保测试该文件是否也具有扩展名。

You can use path.parse(path) , for example例如,您可以使用path.parse(path)

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

I do think mapping the Content-Type header in the request will also work.我确实认为在请求中映射 Content-Type 标头也可以。 This will work even for cases when you upload a file with no extension.即使您上传没有扩展名的文件,这也适用。 (when filename does not have an extension in the request) (当文件名在请求中没有扩展名时)

Assume you are sending your data using HTTP POST:假设您使用 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--

Here name Content-Type header contains the mime type of the data.这里的名称 Content-Type 标头包含数据的 mime 类型。 Mapping this mime type to an extension will get you the file extension :).将此 mime 类型映射到扩展名将为您提供文件扩展名:)。

Restify BodyParser converts this header in to a property with name type 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 } 
}

You can use this header and do the extension mapping (substring etc ...) manually, but there are also ready made libraries for this.您可以使用此标头并手动执行扩展映射(子字符串等...),但也有现成的库。 Below two were the top results when i did a google search以下两个是我进行谷歌搜索时的最佳结果

  • mime哑剧
  • mime-types哑剧类型

and their usage is simple as well:它们的用法也很简单:

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

above snippet will print png to console.上面的代码片段会将png打印到控制台。

import extname in order to return the extension the file: import extname 以返回文件的扩展名:

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

where file is the file 'name' of form其中文件是表单的文件“名称”

A one liner which extends String.prototype :一个扩展String.prototype的衬垫:

Object.defineProperty(String.prototype, "ext", {get: function(x) {return this.split('.').pop()}})
str = 'fox.fbx';
str.ext

Result:结果:

在此处输入图像描述

path.extname will do the trick in most cases. path.extname在大多数情况下都可以解决问题。 However, it will include everything after the last .但是,它将包括最后一个之后的所有内容. , including the query string and hash fragment of an http request: ,包括一个http请求的查询字符串和哈希片段:

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

In such instances, you'll want to try something like this:在这种情况下,你会想尝试这样的事情:

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'

Note that extensions with multiple periods (such as .tar.gz ), will not work at all with path.extname .请注意,带有多个句点的扩展名(例如.tar.gz )根本不适用于path.extname

var fileName = req.files.upload.name;

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

var extension = arr[length-1];

The following function splits the string and returns the name and extension no matter how many dots there are in the extension.以下函数拆分字符串并返回名称和扩展名,无论扩展名中有多少个点。 It returns an empty string for the extension if there is none.如果没有,它将为扩展返回一个空字符串。 Names that start with dots and/or white space work also.以点和/或空格开头的名称也可以使用。

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

Try this one试试这个

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM