【问题标题】:Node.js get file extensionNode.js 获取文件扩展名
【发布时间】:2012-06-07 14:01:18
【问题描述】:

我正在使用 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 中获取图片的扩展名?

【问题讨论】:

标签: javascript node.js file-type


【解决方案1】:

延伸String.prototype:

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

结果:

【讨论】:

    【解决方案2】:

    试试这个

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        import extname 以返回文件的扩展名:

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

        file 是表单的文件“名称”

        【讨论】:

          【解决方案5】:

          使用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 在 cmets 中指出的那样; substr() 现在被视为遗留函数 (MDN documentation)。您可以改用substring()substr()substring() 之间的区别在于 substr() 的第二个参数是要返回的最大长度,而 substring() 的第二个参数是要停止的索引(不包括该字符)。此外,substr() 接受负的起始位置作为从字符串末尾的偏移量,而 substring() 不接受。

          【讨论】:

          • 现在有一个针对substr 的警告,它被认为是遗留功能,应尽可能避免使用 - More information on MDN
          • 在进行 substr(1) 测试时,您还应该考虑 path.extname 所花费的时间
          【解决方案6】:

          无论扩展名中有多少个点,以下函数都会拆分字符串并返回名称和扩展名。如果没有,它将为扩展返回一个空字符串。以点和/或空格开头的名称也可以。

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

          【讨论】:

            【解决方案7】:

            更新

            由于原始答案,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);
            }
            

            【讨论】:

            • 是的,行得通。只是认为使用 node.js 会有更简单的方法。这就是我所做的:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
            • 您应该只使用路径模块,正如@Snowfish 的回答所指出的那样,而不是自己编写。更多信息:nodejs.org/api/path.html#path_path_extname_p
            • 当文件不显示扩展名时怎么办??
            【解决方案8】:

            我确实认为在请求中映射 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 将此标头转换为名称为 type

            的属性
            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 } 
            }
            

            您可以使用此标头并手动进行扩展映射(子字符串等...),但也有现成的库。以下两个是我进行谷歌搜索时的最佳结果

            • 哑剧
            • 哑剧类型

            它们的用法也很简单:

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

            sn-p 上方会打印 png 到控制台。

            【讨论】:

              【解决方案9】:

              此解决方案支持查询字符串!

              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'
              

              【讨论】:

                【解决方案10】:

                一个不需要 require 的简单解决方案,可以解决多期延长问题:

                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'
                

                确保测试文件也有扩展名。

                【讨论】:

                  【解决方案11】:
                  var fileName = req.files.upload.name;
                  
                  var arr = fileName.split('.');
                  
                  var extension = arr[length-1];
                  

                  【讨论】:

                  • 长度变量从何而来?
                  • 尝试为您的答案添加一些解释。这样,OP 就可以真正理解你做了什么以及你为什么这样做。这样,OP 可以从您的答案中学习,而不仅仅是复制/粘贴它。
                  【解决方案12】:

                  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

                  【讨论】:

                    【解决方案13】:
                    // you can send full url here
                    function getExtension(filename) {
                        return filename.split('.').pop();
                    }
                    

                    如果你使用express,请在配置中间件(bodyParser)时添加以下行

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

                    【讨论】:

                      【解决方案14】:

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

                      var path = require('path')
                      
                      path.extname('index.html')
                      // returns
                      '.html'
                      

                      【讨论】:

                      • 小心,它只会抓取最后一个点之后的字符,所以像app.css.gz 这样的文件名只会返回.gz 而不是.css.gz,这可能是也可能不是你的想要。
                      • 在这种情况下,只需使用filename.split('.').pop();
                      • @AamirAfridi 返回相同的字符串,只是没有.
                      • 尝试'filename.css.gz'.split('.').slice(1).join('.') 获取所有个扩展
                      • 一般扩展名是最后一个。当我们期待不止一个时,例如 tar.gz。最好检查它最终是否存在。例如使用正则表达式。 “tar.gz$”或通过建立一个功能来做到这一点。就像从最后检查并返回并查看它是否完全匹配。您将拥有检查扩展名的功能。 为什么?因为像jone.lastTest.654654556.tar.gz 这样的文件呢?这里预期的扩展名是 tar.gz 但是如果你应用任何给出第一个点的函数,它就不会像你看到的那样工作
                      猜你喜欢
                      • 1970-01-01
                      • 2016-09-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-04-14
                      • 2012-03-24
                      • 2010-11-23
                      • 2023-03-09
                      • 1970-01-01
                      相关资源
                      最近更新 更多