我使用multer。
当我将以下代码段放在app.js
app.use(multer({
dest: './uploads'
}
).single('file'));
它在根文件夹下创建了一个新文件夹,我的问题是关于这个新文件夹的生命周期,什么时候被删除? 100次通话后文件夹的大小可以是多少?
如果我不想限制文件大小,我应该在配置中添加什么内容?
app.use(multer({
dest: './public/profile/img/',
limits: {
fieldNameSize: 50,
files: 1,
fields: 5,
fileSize: 1024 * 1024
},
更新
我的应用程序就像
一样构建app.js文件包含
app.use(multer({
dest: './uploads'
}
).single('file'));
app.use('/', routes, function (req, res, next) {
next();
});
路线文件如下所示
appRouter
.post('*', function (req, res) {
handler.dispatch(req, res)
})
.get('*', function (req, res) {
handler.dispatch(req, res)
})
在第三个文件中,我使用解压缩,如下面的
update: function (req, res) {
var filePath = path.join(req.file.destination, req.file.filename);
var unzipper = new Unzipper(filePath);
unzipper.on("extract", function () {
console.log("Finished extracting");
res.sendStatus(200);
});
unzipper.on('progress', function (fileIndex, fileCount) {
console.log('Extracted file ' + (fileIndex + 1) + ' of ' + fileCount);
});
unzipper.on('list', function (files) {
console.log('The archive contains:');
console.log(files);
});
unzipper.on('error', function (err) {
console.log('Caught an error', err);
});
unzipper.extract({
path: "./"
});
}
下面是我的节点应用程序的结构,有人可以建议如何以及在哪里(哪个文件)其推荐使用Raf代码并在文件中添加dateTime我可以添加排序...
答案 0 :(得分:8)
我会尝试用一个真实的例子回答你的问题,至少你可以从中学到一些东西。如果您希望删除除最近上传之外的所有内容,那么您需要编写某种逻辑来区分哪些上载是最近的以及哪些是旧的。我在下面描述,我将如何解决这个问题,可能不完美但是,我就是这样做的。
除非您手动或以编程方式删除该文件夹,否则永远不会自动删除该文件夹。
包含100个电话的文件夹的大小,假设您在每次通话中上传x大小的文件时x将乘以100
您不希望限制文件上传,不提供限制配置,但建议您指定文件上传限制。
您显然可以将multer附加到应用程序或创建它的实例并将其传递给路径。我更喜欢第二种方法:
multer config
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();
});
假设您继续上传,然后在某些时候您要列出uploads目录中的所有文件。路线如下:
列出uploads目录中的所有文件
//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);
});
您想删除上传目录中的所有文件,路线如下所示:
删除上传目录中的所有文件
//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();
});
我的示例中没有添加任何限制,但建议使用。默认文件大小限制是无限的,如果您不将其包含在prod环境中,那么您将容易受到注释中指示的DoS攻击。
要使上述文件操作正常工作,您需要加载
var fs = require('fs');
关于你的第二点,只需跳过limits属性,默认限制将是无穷大。
出于演示目的,我在一个工作的nodejs app中设置了上述内容,见下文:
<强> 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")
答案 1 :(得分:1)
(1)当您进行以下调用时,您告诉multer将上传的文件放入名为uploads
的目录中。因此,如果您的应用启动时它已经不存在,它将为您创建该目录。
app.use(multer({
dest: './uploads'
}
).single('file'));
就该目录的生命周期而言,只要您不删除它,它仍会留在那里,并且仍然要求multer将其用作目的地。在那里添加了上传的文件,因此其内容的大小取决于上传的内容。
(2)至于限制文件大小,根据文档的默认值是无限。所以除非你设置一个,否则没有限制。
但是,不知道你的应用程序,我仍然强烈建议设置一个限制,即使你需要它相当高。完全消除大小限制可能会导致严重问题。
修改强>
如果您想在上传新文件时删除./uploads
的内容,Node会提供删除文件的方法:fs.unlink。另请参阅SO about removing a file in node
在您的上传处理程序中,检查./uploads
和unlink
的任何内容,这些文件不是当前请求中使用的文件。有关当前上传的信息,请参阅req.file
。
答案 2 :(得分:0)
Que 1)您可以决定文件夹的生命周期。
如果您使用 Amazon S3 等第三方进行存储,则无需在本地存储,只要将其上传到服务器即可从本地存储中删除。 发送回复时,您可以使用after Hook。
app.use(function (req, res, next) {
function afterResponse() {
res.removeListener('finish', afterRequest);
res.removeListener('close', afterRequest);
// Delete files from multer
// you can delete older one from upload folder as you see new one came here.
}
res.on('finish', afterResponse);
res.on('close', afterResponse);
// action before request
// eventually calling `next()`
});
Que 2)默认是无限的。