繁体   English   中英

Multer用数据创建新文件夹

[英]Multer create new folder with data

我用multer

问题1

当我在app.js放入以下代码段时

app.use(multer({
        dest: './uploads'
    }
).single('file'));

它在根文件夹下创建了一个新文件夹,我的问题是关于这个新文件夹的lifeCycle,什么时候会被删除? 100次通话后文件夹的大小是多少?

问题2

如果我不想限制文件大小,我应该在配置中添加什么?

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,我可以添加排序...

我将尝试用一个真实的例子来回答你的问题,至少你可以从中学到一些东西。 如果您希望删除除最近上传之外的所有内容,那么您需要编写某种逻辑来区分哪些上载是最近的以及哪些是旧的。 我在下面描述,我将如何解决这个问题,可能不完美但是,我就是这样做的。

除非您手动或以编程方式删除该文件夹,否则永远不会自动删除该文件夹。

假设在每次调用中上传x大小的文件时,100个调用的文件夹大小将乘以x乘以100

您不希望限制文件上载,不提供限制配置,但建议指定文件上载限制。

您显然可以将multer附加到应用程序或创建它的实例并将其传递给路径。 我更喜欢第二种方法:

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();
});

假设你继续上传,然后在某些时候你要列出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);
});

您想删除上传目录中的所有文件,路由如下所示:

删除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();
});

我没有在我的例子中添加任何限制,但是,建议。 默认文件大小限制是无限的,如果您不将其包含在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)当您进行以下调用时,您告诉multer将上载的文件放入名为uploads的目录中。 因此,如果您的应用启动时它尚未存在,它将为您创建该目录。

app.use(multer({
        dest: './uploads'
    }
).single('file'));

就目录的生命周期而言,只要你不删除它,它就会保留在那里,并且仍然要求multer将它用作目的地。 在那里添加了上传的文件,因此其内容的大小取决于上传的内容。

(2)对于限制文件大小,根据文档的默认值是Infinity。 所以除非你设置一个,否则没有限制。

但是,不知道你的应用程序,我仍然强烈建议设置一个限制,即使你需要它相当高。 完全消除大小限制可能会导致严重问题。


编辑
如果要在上载新文件时删除./uploads的内容,Node会提供删除文件的方法: fs.unlink 另请参阅有关删除节点中的文件的信息

在上传处理程序中,检查./uploads的内容,并unlink任何不是当前请求中使用的文件的文件。 有关当前上载的信息,请参阅req.file

Que 1)您可以决定文件夹的生命周期。

  1. 如果您想在服务器上存储文件并在任何时候将文件大小限制回来,您需要更大的存储空间
  2. 如果您使用Amazon S3等第三方进行存储,则无需在本地存储,只要将其上传到服务器即可从本地存储中删除。 您可以发送响应使用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)默认是无限的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM