Express fileupload的mv()方法覆盖同名文件后尺寸未更新,求修复
解决Express mv替换文件后sharp读取旧分辨率的问题
当用Express的mv()方法替换同名图片文件后,sharp.js获取到的仍是旧文件的分辨率,主要有两个常见原因:
mv()是异步操作,若在文件未完成替换时就调用sharp读取,会读到旧文件内容- 操作系统或sharp内部的缓存机制,覆盖式替换文件时inode未改变,sharp复用了之前的缓存数据
方案1:确保mv完成后再执行sharp操作
mv()是异步方法,必须在其回调内(或用Promise+async/await)执行sharp的读取逻辑,保证文件完全替换后再处理。
回调方式修改代码:
let fileInfo = req.files.fileInfo; fileInfo.mv(`/tmp/${fileInfo.name}`, function(err) { if (err) throw err; // 别忘了处理移动失败的错误 console.log("File is moved"); // 此处调用sharp读取分辨率 sharp(`/tmp/${fileInfo.name}`) .metadata() .then(metadata => { console.log('图片分辨率:', metadata.width, 'x', metadata.height); }) .catch(err => { console.error('读取图片元数据失败:', err); }); });
Async/Await方式(更简洁):
const util = require('util'); const mv = util.promisify(fileInfo.mv.bind(fileInfo)); async function handleUpload() { let fileInfo = req.files.fileInfo; try { await mv(`/tmp/${fileInfo.name}`); console.log("File is moved"); const metadata = await sharp(`/tmp/${fileInfo.name}`).metadata(); console.log('图片分辨率:', metadata.width, 'x', metadata.height); } catch (err) { console.error('处理失败:', err); } } handleUpload();
方案2:绕过缓存(方案1无效时使用)
如果确认文件已替换但sharp仍返回旧数据,可通过以下两种方式规避缓存问题:
方法A:禁用sharp缓存
sharp(`/tmp/${fileInfo.name}`, { cache: false }) .metadata() .then(metadata => { console.log('图片分辨率:', metadata.width, 'x', metadata.height); });
方法B:先删除旧文件再移动新文件
先删除目标路径的旧文件,再执行移动操作,确保新文件的inode与旧文件不同,避免系统缓存干扰:
const fs = require('fs').promises; const util = require('util'); const mv = util.promisify(fileInfo.mv.bind(fileInfo)); async function handleUpload() { let fileInfo = req.files.fileInfo; const targetPath = `/tmp/${fileInfo.name}`; try { // 尝试删除旧文件,文件不存在时忽略错误 await fs.unlink(targetPath).catch(() => {}); await mv(targetPath); console.log("File is moved"); const metadata = await sharp(targetPath).metadata(); console.log('图片分辨率:', metadata.width, 'x', metadata.height); } catch (err) { console.error('处理失败:', err); } } handleUpload();
内容的提问来源于stack exchange,提问作者Mary
相关产品推荐
相关产品推荐

