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?

georgesamper
fuente
1
stackoverflow.com/questions/10431845/… ¿repetir?
factura autómata
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'
Pez nieve
fuente
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);
}
dievardump
fuente
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}));
Kamrul
fuente
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.

magikMaker
fuente
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'
aleclarson
fuente
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.

smileham
fuente
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.

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

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

var extension = arr[length-1];
rajesh
fuente
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.

excavado
fuente
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')
Vidar
fuente
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

Vitales
fuente
0

Puede usar path.parse (ruta) , por ejemplo

const path = require('path');
const { ext } = path.parse('/home/user/dir/file.txt');
ns16
fuente
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'));
tunnckoCore
fuente