Multer使用数据创建新文件夹 [英] Multer create new folder with data

查看:163
本文介绍了Multer使用数据创建新文件夹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 multer .

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

When I put the following snippet in the app.js

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

它在根文件夹下创建一个新文件夹,我的问题是关于这个新文件夹的生命周期,何时将其删除?通话100次后文件夹的大小是多少?

it creates a new folder under the root folder, my question is about this new folder's lifeCycle, When it'll be deleted? How much the size of the folder could be after 100 call?

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

If I don't want to limit the file size, what I should put in the configuration?

app.use(multer({
    dest: './public/profile/img/',
    limits: {
        fieldNameSize: 50,
        files: 1,
        fields: 5,
        fileSize: 1024 * 1024
    },

更新

我的应用程序的构建方式类似于

My app is built like

app.js文件包含

app.js file contain

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

在第三个文件中,我像下面这样使用解压缩

And in third file I use the unzip like following

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并添加排序时间. ...

The below is how my node Application is structured, can someone please advice how and where(which file) its recommended to use the Raf code with adding a dateTime to the file which I can add sorting ...

推荐答案

我将尝试通过一个真实的例子来回答您的问题,至少您可能会从中学习一些东西.如果您希望删除除最新上传以外的所有内容,则需要编写某种逻辑代码,以区分是最近上传还是旧上传.在下面我描述,如何解决这个问题可能并不完美,但这就是我的方法.

I will try to answer your question with a real life example, at least you might learn some stuff from it. If you wish to delete all except the most recent upload, then you need to code some sort of logic to differentiate between which upload is recent and which ones are old. Below I describe, how I would go about solving this issue, might not be perfect but, that is how I do it.

该文件夹永远不会被自动删除,除非您手动或以编程方式将其删除.

假设每次上传一个x大小的文件将x乘以100

您不想限制文件上传,不提供限制配置,但是建议指定文件上传限制.

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

You can obviously attach the multer to the app or create an instance of it and pass that to a route. I prefer the second method:

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(),这将为我提供当前时间戳,并附带上载的文件扩展名.如果我进行了6次上传,则它们将显示如下(我的大多数上传文件都是.jpg,这是从文件名中提取的).

As shown above, I do not let multer give a random name to the uploaded file. What I do is, get the file name, strip off its extension and then use Date.now() which will give me the current timestamp appended with the uploaded file extension. If I make six uploads, they would show as follow (most of my uploads were .jpg, that's taken from filename).

上传的最终结果(时间戳会有所不同)

1453414099665.jpg (oldest) 
1453414746114.JPG
1453414748991.jpg
1453414751662.jpg
1453414754815.jpg (most recent)

我将上述storage附加到multer实例,如下所示:

I attached the above storage to an instance of multer as follow:

var upload = multer({storage: storage});

现在,我可以将upload传递到处理文件上传的路由,如下所示:

Now I can pass the upload to a route which handle the file upload as follow:

按如下所示将上传内容附加到路线

//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目录中的所有文件.路线如下:

Let's say you keep uploading and then at some point you want to list all files in the uploads directory. The route would be as follow:

列出上传目录中的所有文件

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

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

You want to delete all files in the upload directory, the route would look as follow:

删除上传目录中的所有文件

//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)

If you wish to delete all files synchronously then you have to invoke the sync version of readdir (readdirSync) and unlink (unlinkSync)

var filenames = fs.readdirSync('./uploads');

filenames.forEach(function(file) {
  fs.unlinkSync('./uploads/' + file);
});

现在,您要删除所有文件(最新上传的文件除外).好吧,我已经将所有文件名都设为了时间戳.因此,我将执行以下操作:

Now to your point of deleting all but, the most recent uploaded file. Well, I have already made all filename be timestamps. So I would do something as follow:

删除所有文件,除了最新的文件(最新的文件名是带有最新时间戳的文件).

Delete all files except most recent (where most recent being the one with most recent timestamp as its filename).

//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攻击,如注释中所示.

I have not added any limits in my example but, it is recommended. The default file size limit is infinity and if you don't include it in a prod environment then you will be vulnerable to DoS attacks as indicated in the comments.

要使上述文件操作正常工作,您需要加载

For the above file operation to work you need to load

var fs = require('fs'); 

关于第二点,只需跳过limits属性,默认限制将为无穷大.

In regards to your second point, simply skip the limits property and the default limit will be infinity.

出于演示目的,我已经在可运行的nodejs应用程序中设置了以上内容,请参见下文:

For demonstration purposes, I have setup the above in a working nodejs app, see below:

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

views/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")

这篇关于Multer使用数据创建新文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆