Node.js รับนามสกุลไฟล์


209

ฉันกำลังสร้างฟังก์ชั่นอัพโหลดไฟล์ใน node.js ด้วย express 3

ฉันต้องการคว้านามสกุลไฟล์ของภาพ ดังนั้นฉันสามารถเปลี่ยนชื่อไฟล์และต่อท้ายนามสกุลไฟล์นั้น

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 ได้อย่างไร?


1
stackoverflow.com/questions/10431845/…ทำซ้ำหรือไม่
bill automata

3
ไม่ใช่คำถามเกี่ยวกับประเภท mime นั้นฉันต้องการนามสกุลไฟล์
georgesamper

คำตอบ:


473

ฉันเชื่อว่าคุณสามารถทำสิ่งต่อไปนี้เพื่อรับส่วนขยายของชื่อไฟล์

var path = require('path')

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

54
เพียงแค่ระวังมันจะจับตัวละครหลังจากจุดสุดท้ายดังนั้นชื่อไฟล์เช่นapp.css.gzจะกลับมา.gzและไม่.css.gzซึ่งอาจหรืออาจไม่ใช่สิ่งที่คุณต้องการ
xentek

18
ในกรณีดังกล่าวให้ใช้เพียงfilename.split('.').pop();
Aamir Afridi

12
@AamirAfridi .ผลตอบแทนที่สตริงเดียวกันเพียงโดยไม่ต้อง
ไม่ได้กำหนด

13
พยายามที่'filename.css.gz'.split('.').slice(1).join('.')จะได้รับส่วนขยายทั้งหมด
เทรเวอร์

10
โดยทั่วไปส่วนขยายเป็นนามสกุลสุดท้าย และเมื่อเราคาดหวังมากกว่าหนึ่งตัวอย่างเช่น tar.gz มันเป็นการดีกว่าที่จะตรวจสอบว่ามันมีอยู่ในตอนท้ายหรือไม่ ใช้ regex ตัวอย่างเช่น "tar.gz $" หรือโดยการสร้างฟังก์ชันที่ทำเช่นนั้น เหมือนการตรวจสอบตั้งแต่ต้นจนจบและย้อนกลับไปดูว่าตรงกันหรือไม่ และคุณจะมีฟังก์ชั่นที่ตรวจสอบส่วนขยาย ทำไม? เพราะjone.lastTest.654654556.tar.gz ส่วนขยายของไฟล์อย่างที่คาดหวังคือ tar.gz แต่ถ้าคุณใช้ฟังก์ชั่นที่ให้รูปแบบที่ 1 จุดมันจะไม่ทำงานอย่างที่คุณเห็น
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
คุณควรใช้โมดูล path อย่างที่คำตอบของ @ Snowfish ชี้ให้เห็นและอย่าเขียนด้วยตัวคุณเอง ข้อมูลเพิ่มเติม: nodejs.org/api/path.html#path_path_extname_p
xentek

และสิ่งที่เกี่ยวกับเมื่อไฟล์ไม่ได้แสดงนามสกุล?
oldboy

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

ถ้าคุณใช้ด่วนกรุณาเพิ่มบรรทัดต่อไปนี้เมื่อกำหนดค่ามิดเดิลแวร์ (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 ตามที่ระบุโดย @xentek ในความคิดเห็น substr()ขณะนี้ถือว่าเป็นฟังก์ชันดั้งเดิม ( เอกสาร MDN ) คุณสามารถใช้substring()แทน ความแตกต่างระหว่างsubstr()และsubstring()คืออาร์กิวเมนต์ที่สองของsubstr()คือความยาวสูงสุดที่จะส่งคืนขณะที่อาร์กิวเมนต์ที่สองของsubstring()คือดัชนีที่จะหยุดที่ (โดยไม่รวมอักขระนั้น) นอกจากนี้ยังsubstr()ยอมรับตำแหน่งเริ่มต้นเชิงลบที่จะใช้เป็นออฟเซ็ตจากจุดสิ้นสุดของสตริงในขณะที่substring()ไม่


มีคำเตือนในขณะนี้เพราะsubstrถือว่าเป็นฟังก์ชั่นดั้งเดิมและควรหลีกเลี่ยงเมื่อเป็นไปได้ - ข้อมูลเพิ่มเติมเกี่ยวกับ MDN
Core972

เมื่อทำการทดสอบ substr (1) คุณควรคำนึงถึงเวลาที่ใช้ในการพิจารณาเส้นทางชื่อ
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

ทางออกที่ง่ายโดยไม่จำเป็นต้องมีซึ่งช่วยแก้ไขปัญหาการขยายระยะเวลาหลายช่วง:

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

ฉันคิดว่าการจับคู่ส่วนหัวของประเภทเนื้อหาในคำขอจะใช้งานได้เช่นกัน สิ่งนี้จะทำงานได้แม้ในกรณีที่คุณอัปโหลดไฟล์ที่ไม่มีนามสกุล (เมื่อชื่อไฟล์ไม่มีส่วนขยายในคำขอ)

สมมติว่าคุณกำลังส่งข้อมูลของคุณโดยใช้ 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--

ที่นี่ชื่อส่วนหัวของประเภทเนื้อหามีประเภท 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 } 
}

คุณสามารถใช้ส่วนหัวนี้และทำการแมปส่วนขยาย (สตริงย่อย ฯลฯ ... ) ด้วยตนเอง แต่ยังมีไลบรารีที่ทำสำหรับสิ่งนี้ ด้านล่างทั้งสองเป็นผลลัพธ์อันดับต้น ๆ เมื่อฉันค้นหาด้วยกูเกิ้ล

  • ละครใบ้
  • ประเภท 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
ตัวแปรความยาวมาจากไหน
Angel S. Moreno

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.