Node.js get file extension

Javascriptnode.jsFile Type

Javascript Problem Overview


Im creating a file upload function in node.js with express 3.

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.

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?

Javascript Solutions


Solution 1 - Javascript

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'

Solution 2 - Javascript

Update

Since the original answer, extname() has been added to the path module, see Snowfish answer

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

Solution 3 - Javascript

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

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

Solution 4 - Javascript

It's a lot more efficient to use the substr() method instead of split() & pop()

Have a look at the performance differences here: http://jsperf.com/remove-first-character-from-string

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

enter image description here

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.

Solution 5 - Javascript

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'

Solution 6 - Javascript

A simple solution without need for require which solves the multiple period extension problem:

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.

Solution 7 - Javascript

You can use path.parse(path), for example

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

Solution 8 - Javascript

I do think mapping the Content-Type header in the request will also work. 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:

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. Mapping this mime type to an extension will get you the file extension :).

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

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.

Solution 9 - Javascript

import extname in order to return the extension the file:

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

where file is the file 'name' of form

Solution 10 - Javascript

A one liner which extends String.prototype:

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

Result:

enter image description here

Solution 11 - Javascript

path.extname will do the trick in most cases. However, it will include everything after the last ., including the query string and hash fragment of an http request:

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.

Solution 12 - Javascript

var fileName = req.files.upload.name;

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

var extension = arr[length-1];

Solution 13 - Javascript

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

Solution 14 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongeorgesamperView Question on Stackoverflow
Solution 1 - JavascriptSnowfishView Answer on Stackoverflow
Solution 2 - JavascriptdievardumpView Answer on Stackoverflow
Solution 3 - JavascriptKamrulView Answer on Stackoverflow
Solution 4 - JavascriptmagikMakerView Answer on Stackoverflow
Solution 5 - JavascriptaleclarsonView Answer on Stackoverflow
Solution 6 - JavascriptsmilehamView Answer on Stackoverflow
Solution 7 - Javascriptns16View Answer on Stackoverflow
Solution 8 - JavascriptrozaydinView Answer on Stackoverflow
Solution 9 - JavascriptVitalvesView Answer on Stackoverflow
Solution 10 - JavascriptkungfoomanView Answer on Stackoverflow
Solution 11 - JavascriptdugView Answer on Stackoverflow
Solution 12 - JavascriptrajeshView Answer on Stackoverflow
Solution 13 - JavascriptVidarView Answer on Stackoverflow
Solution 14 - JavascripttunnckoCoreView Answer on Stackoverflow