我会尝试用一个现实生活中的例子来回答你的问题,至少你可以从中学到一些东西。如果您希望删除除最近上传的所有内容,那么您需要编写某种逻辑来区分哪些上传是最近的,哪些是旧的。下面我描述了我将如何解决这个问题,可能并不完美,但我就是这样做的。
该文件夹永远不会自动删除,除非您手动或以编程方式删除它。
包含 100 个调用的文件夹的大小,假设在每次调用中您上传 x 大小的文件将是 x 乘以 100
您不想限制文件上传,请勿提供限制配置,但建议指定文件上传限制。
显然,您可以将 multer 连接到应用程序或创建它的实例并将其传递给路由。我更喜欢第二种方法:
多路复用器配置
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
var filename = file.originalname;
var fileExtension = filename.split(".")[1];
cb(null, Date.now() + "." + fileExtension);
}
});
如上所示,我不让 multer 给上传的文件起一个随机名称。我所做的是,获取文件名,去掉其扩展名,然后使用Date.now()
这将为我提供当前时间戳并附加上传的文件扩展名。如果我上传六个,它们将显示如下(我的大部分上传都是 .jpg,取自文件名)。
上传将如何结束(时间戳会有所不同)
1453414099665.jpg (oldest)
1453414746114.JPG
1453414748991.jpg
1453414751662.jpg
1453414754815.jpg (most recent)
我附上上面的storage
到 multer 实例如下:
var upload = multer({storage: storage});
现在我可以通过upload
到处理文件上传的路由,如下所示:
将上传附加到路由,如下所示
//simple route to return upload form, simple jade file
app.get('/upload', function(req, res){
res.render('upload');
});
//this route processes the upload request, see below upload.single('file')
//is the passed multer
app.post('/upload', upload.single('file'), function(req,res){
res.status(204).end();
});
假设您继续上传,然后在某个时刻您想要列出上传目录中的所有文件。路线如下:
列出上传目录中的所有文件
//lists all files in the uploads directory and return it to browser as json response
app.get('/listAllFiles', function(req, res) {
//reading directory in synchronous way
var files = fs.readdirSync('./uploads');
res.json(files);
});
您想删除上传目录中的所有文件,路线如下:
删除uploads目录下的所有文件
//delete all files in the upload direcotry asynchronously
app.get('/deleteAllFiles', function(req, res) {
fs.readdir('./uploads', function(err, items) {
items.forEach(function(file) {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
});
res.status(204).end();
});
});
如果您希望同步删除所有文件,则必须调用 readdir 的同步版本(readdirSync)和取消链接(unlinkSync)
var filenames = fs.readdirSync('./uploads');
filenames.forEach(function(file) {
fs.unlinkSync('./uploads/' + file);
});
现在,删除除最近上传的文件之外的所有文件。好吧,我已经将所有文件名设置为时间戳。所以我会做如下的事情:
删除除最新文件之外的所有文件(其中最新文件是以最新时间戳作为文件名的文件)。
//delets all file asynchronously except the most recent in which case the file
//with name being the latest timestamp is skipped.
app.get('/deleteAllExceptMostRecent', function(req, res) {
console.log('/deleteAllFilesExceptMostRecent');
fs.readdir('./uploads', function(err, items) {
//sort the array of files names in reverse, so we have most recent file on top
items.reverse();
var flag = true;
items.forEach(function(file) {
//skip deletion of most recent file. if condition executed onces only.
if(flag) {
flag = false;
} else {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
}
});
});
res.status(204).end();
});
我没有在我的示例中添加任何限制,但建议这样做。默认文件大小限制是无穷大,如果您不将其包含在产品环境中,那么您将容易受到 DoS 攻击,如注释中所示。
为了使上述文件操作起作用,您需要加载
var fs = require('fs');
关于第二点,只需跳过限制属性,默认限制将为无穷大。
出于演示目的,我在工作的 Nodejs 应用程序中设置了上述内容,如下所示:
app.js
var express = require('express');
var multer = require('multer');
var bodyParser = require('body-parser');
var path = require('path');
var fs = require('fs');
var app = new express();
app.use(bodyParser.json());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
/* if you need to retain the original filename, then use filename and append to it date
* if you don't need original filename but, just extension, then append extension at the
* end of current timestamp. If you don't need extenion then just use Date.now() which
*/
var filename = file.originalname;
var fileExtension = filename.split(".")[1];
cb(null, Date.now() + "." + fileExtension);
}
})
var upload = multer({storage: storage});
//get upload form
app.get('/upload', function(req, res){
res.render('upload');
});
//process upload
app.post('/upload', upload.single('file'), function(req,res){
res.status(204).end();
});
//lists all files in the uploads directory.
app.get('/listAllFiles', function(req, res) {
var files = fs.readdirSync('./uploads');
res.json(files);
});
//delete all files in the upload direcotry asynchronously
app.get('/deleteAllFiles', function(req, res) {
fs.readdir('./uploads', function(err, items) {
items.forEach(function(file) {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
});
res.status(204).end();
});
});
//delets all file asynchronously except the most recent in which case the file
//with name being the latest timestamp is skipped.
app.get('/deleteAllExceptMostRecent', function(req, res) {
console.log('/deleteAllFilesExceptMostRecent');
fs.readdir('./uploads', function(err, items) {
items.reverse();
var flag = true;
items.forEach(function(file) {
if(flag) {
flag = false;
} else {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
}
});
});
res.status(204).end();
});
//delete all files of a direcotry in synchronous way
app.get('/deleteAllSync', function(req, res) {
var filenames = fs.readdirSync('./uploads');
filenames.forEach(function(file) {
fs.unlinkSync('./uploads/' + file);
});
});
//delete all files except most recent in synchronous way
app.get('/deleteAllSyncExceptMostRecent', function(req, res) {
var filenames = fs.readdirSync('./uploads');
filenames.reverse();
var flag = true;
filenames.forEach(function(file) {
if(flag)
flag = false;
else
fs.unlinkSync('./uploads/' + file);
});
});
var port = 3000;
app.listen( port, function(){ console.log('listening on port '+port); } );
视图/upload.jade
html
head
title
body
form(method="post",enctype="multipart/form-data",action="/upload")
p
input(type="file",name="file")
p
input(type="submit")