如何设置multer使上传的临时文件在指定时长后自动删除?
解决方案
方案1:定时兜底清理临时目录(最稳妥)
这个方案和上传逻辑完全解耦,不受服务崩溃、异常报错影响,是必备的兜底方案。
- 方式一:Linux服务器直接用crontab定时任务,添加如下规则即可,不需要额外引入Node依赖:
0 2 * * * find /你的项目完整路径/public/uploads -type f -mmin +60 -delete
以上规则代表每天凌晨2点,删除上传目录下创建时间超过60分钟的文件,你可以根据自己的业务需求调整执行频率和保留时长。
- 方式二:Node层面用定时任务库实现,适合跨平台部署的场景:
首先安装依赖:npm install node-schedule
然后在项目启动文件中添加如下代码:
const schedule = require('node-schedule'); const fs = require('fs/promises'); const path = require('path'); const UPLOAD_DIR = './public/uploads/'; // 文件保留时长,单位为毫秒,这里设置为1小时 const RETENTION_TIME = 60 * 60 * 1000; // 每天凌晨2点执行清理任务,可根据需求调整cron表达式 const cleanJob = schedule.scheduleJob('0 0 2 * * *', async () => { try { const files = await fs.readdir(UPLOAD_DIR); const now = Date.now(); for (const file of files) { const filePath = path.join(UPLOAD_DIR, file); const stat = await fs.stat(filePath); if (stat.isFile() && now - stat.birthtimeMs > RETENTION_TIME) { await fs.unlink(filePath); console.log(`过期文件已删除:${file}`); } } } catch (err) { console.error('临时文件清理失败:', err); } });
方案2:Multer存储逻辑新增自动延迟删除
可以在文件命名生成的同时加一个定时器,到期自动删除文件,就算业务逻辑漏写删除代码也能自动清理:
修改你的multer配置代码即可:
const storage = multer.diskStorage({ destination: './public/uploads/', filename: function(req, file, cb){ const filename = file.fieldname + '-' + Date.now() + path.extname(file.originalname); cb(null, filename); // 设置1小时后自动删除 const filePath = path.join('./public/uploads/', filename); setTimeout(async () => { try { await fs.access(filePath); await fs.unlink(filePath); } catch (err) { // 文件已经被提前删除的话忽略报错 if (err.code !== 'ENOENT') { console.error(`自动删除文件${filename}失败:`, err); } } }, 60 * 60 * 1000); } });
注意:该方案仅在服务正常运行时生效,如果定时器触发前服务崩溃,本次写入的文件不会被自动删除,必须搭配方案1的定时兜底使用。
方案3:补全现有请求逻辑的删除逻辑,减少正常流程的残留
你当前的代码仅在Imgur上传成功的分支有删除逻辑,报错、无文件上传等分支都漏了删除逻辑,可以把删除操作放到finally块中,不管请求成功失败都会执行删除:
修改后的接口代码如下:
app.post('/upload-image', (req, res) => { upload(req, res, async (err) => { const filePath = req.file ? `./public/uploads/${req.file.filename}` : null; try { if (err) throw err; if (!req.file) throw new Error('Error: No File Selected'); const json = await imgur.uploadFile(filePath); // 这里保留你原来和MongoDB交互的业务逻辑 } catch (err) { console.error(err.message); } finally { // 只要文件存在就执行删除 if (filePath) { fs.unlink(filePath, (err) => { if (err && err.code !== 'ENOENT') { console.error('文件删除失败:', err); } }); } } }); })
三个方案配合使用,就能基本避免临时目录出现大量残留文件的问题。
内容的提问来源于stack exchange,提问作者Alpine_Shell
相关产品推荐
相关产品推荐

