Node.js中无法删除webp图片,报错EBUSY资源繁忙或被锁定
问题原因
EBUSY错误本质是待删除的源图片文件仍被sharp进程占用,文件句柄未释放导致操作系统禁止删除操作,该问题在Windows系统下出现概率更高,因为Windows的文件锁机制比类Unix系统更严格。你当前的代码中,sharp异步回调执行时,sharp实例可能还持有源文件的资源锁,直接调用删除就会触发报错。
解决方案
方案1:主动销毁sharp实例后执行删除
在回调中先调用sharp实例的destroy()方法主动释放资源,配合短延迟适配Windows的锁释放逻辑,修改后代码如下:
let outputFilePath = "public/converted/"+file.originalname.split('.').slice(0, -1).join('.') + "--converted." + format; const sharpInstance = sharp(file.path); sharpInstance.toFile(outputFilePath, (err, info) => { if (err) throw err; // 主动销毁sharp实例释放文件句柄 sharpInstance.destroy(); // 加100ms延迟适配Windows文件锁释放 setTimeout(() => { try{ fs.unlinkSync(file.path) } catch(err){ console.log(err) } }, 100) }) return sharpInstance.options.fileOut;
方案2:改用Promise异步写法更稳妥
用async/await语法搭配promise版API,逻辑更清晰,也更容易控制执行顺序:
const processImage = async () => { let outputFilePath = "public/converted/"+file.originalname.split('.').slice(0, -1).join('.') + "--converted." + format; const sharpInstance = sharp(file.path); try { // 等待格式转换完成 await sharpInstance.toFile(outputFilePath); // 释放资源 sharpInstance.destroy(); // 异步删除源文件 await fs.promises.unlink(file.path); } catch (err) { console.error(err); throw err; } return sharpInstance.options.fileOut; }
方案3:从根源避免文件删除问题
修改multer的存储配置为内存存储,上传的文件不会写入磁盘,直接用Buffer传给sharp处理,完全不需要操作本地临时文件的删除:
- 修改multer配置:
const multer = require('multer'); // 配置内存存储,不写入本地磁盘 const storage = multer.memoryStorage(); const upload = multer({ storage: storage });
- 调整sharp调用逻辑,直接传入文件Buffer:
sharp(file.buffer).toFile(outputFilePath)
内容的提问来源于stack exchange,提问作者Gulzaib
相关产品推荐
相关产品推荐

