Node.js obtener extensión de archivo


209

Estoy creando una función de carga de archivos en node.js con express 3.

Me gustaría tomar la extensión del archivo de la imagen. para poder cambiar el nombre del archivo y luego agregarle la extensión del archivo.

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

¿Cómo puedo obtener la extensión de la imagen en node.js?



3
No es que la pregunta sobre los tipos MIME, quiero que la extensión de archivo
georgesamper

Respuestas:


473

Creo que puede hacer lo siguiente para obtener la extensión de un nombre de archivo.

var path = require('path')

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

54
Solo tenga cuidado, solo tomará los caracteres después del último punto, por lo que los nombres de archivo como app.css.gzsolo volverán .gzy no .css.gz, lo que puede o no ser lo que desea.
xentek

18
En ese caso, simplemente usefilename.split('.').pop();
Aamir Afridi

12
@AamirAfridi Eso devuelve la misma cadena solo sin el ..
indefinido

13
Intenta 'filename.css.gz'.split('.').slice(1).join('.')obtener todas las extensiones
Trevor

10
Generalmente la extensión es la última. Y para cuando esperamos más de uno, como tar.gz por ejemplo. Es mejor comprobar si existe al final o no. usando expresiones regulares por ejemplo. "tar.gz $" o creando una función que haga eso. como verificar eso desde el final y regresar y ver si coincide totalmente. y tendrás esa función que verifica la extensión. ¿POR QUÉ? porque qué pasa con los archivos como jone.lastTest.654654556.tar.gz aquí, la extensión que se espera es tar.gz, pero si aplicas cualquier función que dé el primer punto, no funcionará como puedes ver
Mohamed Allal

33

Actualizar

Desde la respuesta original, extname () se ha agregado al pathmódulo, vea la respuesta de Snowfish

Respuesta original:

Estoy usando esta función para obtener una extensión de archivo, porque no encontré una manera de hacerlo de una manera más fácil (pero creo que la hay):

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

debes requerir 'ruta' para usarlo.

Otro método que no utiliza el módulo de ruta:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}

44
Si eso funciona. Solo pensé que habría una manera más fácil de usar el nodo. Esto es lo que hice:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
georgesamper

66
Realmente deberías usar el módulo de ruta, como señaló la respuesta de @ Snowfish, y no escribir la tuya. Más información: nodejs.org/api/path.html#path_path_extname_p
xentek

¿Y qué pasa cuando los archivos no muestran extensiones?
oldboy

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

Si está utilizando express, agregue la siguiente línea cuando configure middleware (bodyParser)

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

12

Es mucho más eficiente usar el substr()método en lugar de split()&pop()

Eche un vistazo a las diferencias de rendimiento aquí: http://jsperf.com/remove-first-character-from-string

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

ingrese la descripción de la imagen aquí

Actualización de agosto de 2019 Como señaló @xentek en los comentarios; substr()ahora se considera una función heredada ( documentación MDN ). Puedes usar substring()en su lugar. La diferencia entre substr()y substring()es que el segundo argumento de substr()es la longitud máxima para devolver, mientras que el segundo argumento de substring()es el índice para detenerse (sin incluir ese carácter). Además, substr()acepta posiciones de inicio negativas para utilizarlas como un desplazamiento desde el final de la cadena, mientras substring()que no lo hace.


Ahora hay una advertencia porque substrse considera una función heredada y debe evitarse cuando sea posible. Más información sobre MDN
Core972

Al hacer la prueba substr (1) también debe tener en cuenta el tiempo dedicado a path.extname
eugenekr

11

¡Esta solución admite cadenas de consulta!

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

Una solución simple sin necesidad de requerir que resuelva el problema de extensión de períodos múltiples:

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

O si no quieres el punto inicial:

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

Asegúrese de probar que el archivo también tiene una extensión.


4

Creo que mapear el encabezado Content-Type en la solicitud también funcionará. Esto funcionará incluso en los casos en que cargue un archivo sin extensión. (cuando el nombre de archivo no tiene una extensión en la solicitud)

Suponga que está enviando sus datos usando 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--

Aquí el encabezado nombre Content-Type contiene el tipo mime de los datos. Al asignar este tipo MIME a una extensión obtendrá la extensión del archivo :).

Restify BodyParser convierte este encabezado en una propiedad con tipo de nombre

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

Puede usar este encabezado y hacer la asignación de extensión (subcadena, etc.) manualmente, pero también hay bibliotecas listas para esto. Debajo de dos estaban los mejores resultados cuando hice una búsqueda en Google

  • mímica
  • tipos mimo

y su uso también es simple:

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

el fragmento anterior imprimirá png a la consola.


2
var fileName = req.files.upload.name;

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

var extension = arr[length-1];

1
¿De dónde viene la variable de longitud?
Angel S. Moreno

3
Intenta agregar alguna explicación a tu respuesta. De esa manera, el OP puede comprender lo que hizo y por qué lo hizo. De esta forma, el OP puede aprender de su respuesta, en lugar de simplemente copiarla / pegarla.
Oldskool

1

path.extnamehará el truco en la mayoría de los casos. Sin embargo, incluirá todo después del último ., incluida la cadena de consulta y el fragmento hash de una solicitud http:

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

En tales casos, querrás probar algo como esto:

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'

Tenga en cuenta que las extensiones con varios períodos (como .tar.gz) no funcionarán en absoluto con path.extname.


0

La siguiente función divide la cadena y devuelve el nombre y la extensión sin importar cuántos puntos haya en la extensión. Devuelve una cadena vacía para la extensión si no hay ninguna. Los nombres que comienzan con puntos y / o espacios en blanco también funcionan.

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 para devolver la extensión al archivo:

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

donde archivo es el archivo 'nombre' del formulario


0

Puede usar path.parse (ruta) , por ejemplo

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

0

Prueba este

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'));
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.