Node.js getファイル拡張子


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

回答:


473

ファイル名の拡張子を取得するには、次のようにできると思います。

var path = require('path')

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

54
注意してください。最後のドットの後の文字のみを取得するので、などのファイル名app.css.gzはだけを返し.gz、は返されませ.css.gzん。
xentek 2014

18
その場合は、単純に使用してくださいfilename.split('.').pop();
Aamir Afridi

12
@AamirAfridiこれは、なしで同じ文字列を返します.
未定義

13
すべての拡張機能'filename.css.gz'.split('.').slice(1).join('.')を取得てみてください
Trevor

10
通常、拡張子は最後です。そして、例えばtar.gzのように、1つ以上を期待している場合のために。それが最後に存在するかどうかを確認することをお勧めします。たとえば正規表現を使用します。"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

6
@Snowfishの答えが指摘したように、実際にはパスモジュールを使用する必要があり、独自のものを作成するべきではありません。詳細: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()の2番目の引数があることsubstr()の2番目の引数はながらリターン最大長さsubstring()(つまり文字含まず)で停止するインデックスです。また、substr()文字列の末尾からのオフセットとして使用される負の開始位置を受け入れますが、受け入れsubstring()ません。


substrレガシー機能と見なされ、可能な場合は回避する必要があるため、警告が表示されます
-MDNの

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

複数期間延長問題を解決する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'

ファイルにも拡張子があることをテストしてください。


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

このヘッダーを使用して手動で拡張マッピング(部分文字列など)を行うことができますが、これ用に既製のライブラリもあります。下の2つは、Google検索を行ったときの上位の結果です

  • MIME
  • MIMEタイプ

そしてそれらの使い方も簡単です:

 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
長さ変数はどこから来るのですか?
エンジェルS.モレノ

3
解答に説明を加えてください。そうすれば、OPは実際にあなたが何をしたのか、なぜこれをしたのかを理解できます。そうすることで、OPは単にコピー/貼り付けするのではなく、回答から学ぶことができます。
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);

ここで、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'));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.