Подтвердить что ты не робот

Multer создает новую папку с данными

Я использую 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)
    })

И в третьем файле я использую unzip, как показано ниже

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

Ниже описано, как структурировано мое приложение node, может ли кто-нибудь проконсультироваться, как и где (в каком файле) его рекомендуется использовать код Raf с добавлением dateTime к файлу, который я могу добавить сортировку...

4b9b3361

Ответ 1

Я постараюсь ответить на ваш вопрос реальным примером жизни, по крайней мере, вы могли бы изучить некоторые вещи из него. Если вы хотите удалить все, кроме самой последней загрузки, тогда вам нужно закодировать какую-то логику, чтобы различать, какой из последних загрузок и какие старые. Ниже я описываю, как бы я решил решить эту проблему, может быть, не идеально, но вот как я это делаю.

Папка никогда не будет удаляться автоматически, если вы не удалите ее вручную или программно.

Размер папки с 100 вызовами, предполагая, что в каждом вызове вы загружаете файл размером x, будет 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);
  }
}); 

Как показано выше, я не позволяю мультеру давать случайное имя загруженному файлу. То, что я делаю, это получить имя файла, отменить его расширение, а затем использовать 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. Маршрут будет следующим:

Список всех файлов в каталоге загрузок

//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) и unlink (unlinkSync)

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

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

Теперь вам нужно удалить все, кроме самого последнего загруженного файла. Ну, я уже сделал все имена файлов timestamps. Поэтому я бы сделал что-то следующее:

Удалите все файлы, кроме последних (где последнее из них является самым последним в качестве имени файла).

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

Ответ 2

(1). Когда вы делаете следующий вызов, вы говорите, что multer помещает загруженные файлы в каталог с именем uploads. Таким образом, он создаст этот каталог для вас, если он еще не появится, когда ваше приложение запустится.

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

В терминах жизненного цикла этого каталога он останется там до тех пор, пока вы его не удалите, и все еще просят использовать его в качестве адресата. Добавленные файлы добавляются туда, поэтому размер его содержимого зависит от того, что загружается.

(2) Как и для ограничения размера файла, по умолчанию в соответствии с документами понимается Infinity. Таким образом, нет ограничений, если вы не установите его.

Но, не зная вашего приложения, я все же настоятельно рекомендую установить лимит, даже если вам нужно, чтобы он был достаточно высоким. Удаление ограничения размера может привести к большим проблемам.


изменить
Если вы хотите удалить содержимое ./uploads при загрузке нового файла, Node предоставляет способ удаления файла: fs.unlink. См. Также SO об удалении файла в node

В обработчике загрузки проверьте содержимое ./uploads и unlink любого файла, который не является файлом, используемым в текущем запросе. См. req.file для текущей загрузки.

Ответ 3

Que 1) Вы можете определить жизненный цикл папок.

  • Если вы хотите хранить файлы на сервере и возвращать их обратно в любое время без ограничения размера файла, вам нужно больше памяти
  • Если вы используете стороннюю компанию, такую ​​как Amazon S3 для хранения, нет места для локального хранения, как только ее выгрузите на сервер, вы можете удалить ее из локального хранилища. Вы можете использовать после клика после отправки ответа.

    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) По умолчанию безгранично.