Multer crée un nouveau dossier avec des données

J'utilise multer .

question 1

Lorsque j'ai mis l'extrait suivant dans l' app.js

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

Il crée un nouveau dossier sous le dossier racine, ma question concerne le LifeCycle de ce nouveau dossier, quand il sera supprimé? Combien coûte la taille du dossier après 100 appels?

question 2

Si je ne veux pas limiter la taille du fichier, que dois-je mettre dans la configuration?

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

Mettre à jour

Mon application est construite comme

Le fichier app.js contient

  app.use(multer({ dest: './uploads' } ).single('file')); app.use('/', routes, function (req, res, next) { next(); }); 

Le fichier d'itinéraire ressemble à suivre

 appRouter .post('*', function (req, res) { handler.dispatch(req, res) }) .get('*', function (req, res) { handler.dispatch(req, res) }) 

Et dans le troisième fichier, j'utilise le décompression comme suit

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

Voici comment mon noeud est structuré, est-ce que quelqu'un peut conseiller comment et où (quel fichier) il est recommandé d'utiliser le code Raf avec l'ajout d'une dateTime au fichier que je peux ajouter le tri …

Je vais essayer de répondre à votre question avec un exemple de vie réelle, du moins, vous pourriez en apprendre davantage. Si vous souhaitez supprimer tout sauf le téléchargement le plus récent, vous devez coder une sorte de logique pour différencier le téléchargement de ce dernier et ceux qui sont anciens. Ci-dessous, je décris, comment je parviendrais à résoudre ce problème, peut-être pas parfait, mais c'est ainsi que je le fais.

Le dossier ne sera jamais supprimé automatiquement, sauf si vous le supprimez manuellement ou par programme.

La taille du dossier avec 100 appels en supposant que dans chaque appel que vous téléchargez un fichier de x taille serait multiplié par 100 par 100

Vous ne souhaitez pas limiter le téléchargement du fichier, ne fournissez pas de configurations de limites, mais il est recommandé de spécifier une limite de téléchargement de fichier.

Vous pouvez, évidemment, attacher le multer à l'application ou en créer une instance et la transmettre à un itinéraire. Je préfère la deuxième méthode:

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

Comme indiqué ci-dessus, je ne laisse pas Multer donner un nom aléatoire au fichier téléchargé. Ce que je fais, obtenez le nom du fichier, Date.now() son extension et utilisez Date.now() qui me donnera l'horodatage actuel ajouté à l'extension de fichier téléchargé. Si je fais six téléchargements, ils montreraient comme suit (la plupart de mes téléchargements étaient .jpg, cela a été retiré du nom de fichier).

Comment les téléchargements finiraient (les horodateurs seraient différents)

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

J'ai attaché le storage ci-dessus à une instance de multer comme suit:

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

Maintenant, je peux passer le upload vers un itinéraire qui gère le téléchargement du fichier comme suit:

Attachez le téléchargement à l'itinéraire comme indiqué ci-dessous

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

Disons que vous continuez à télécharger, puis vous souhaitez ensuite répertorier tous les fichiers dans le répertoire des téléchargements. L'itinéraire serait le suivant:

Liste tous les fichiers dans le répertoire des téléchargements

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

Vous souhaitez supprimer tous les fichiers dans le répertoire de téléchargement, l'itinéraire devrait être le suivant:

Supprimer tous les fichiers dans le répertoire des téléchargements

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

Si vous souhaitez supprimer tous les fichiers de façon synchrone, vous devez appeler la version de synchronisation de readdir (readdirSync) et déconnecter (unlinkSync)

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

Maintenant à votre place de supprimer tout sauf le fichier téléchargé le plus récent. Eh bien, j'ai déjà fait que tous les noms de fichiers soient des horodateurs. Donc, je ferais quelque chose comme suit:

Supprimez tous les fichiers, sauf les plus récents (où le plus récent est celui avec l'horodatage le plus récent comme son nom de fichier).

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

Je n'ai ajouté aucune limite dans mon exemple mais, il est recommandé. La limite de taille de fichier par défaut est infinie et si vous ne l'incluez pas dans un environnement de produit, vous serez vulnérable aux attaques DoS comme indiqué dans les commentaires.

Pour que l'opération de fichier ci-dessus fonctionne, vous devez charger

 var fs = require('fs'); 

En ce qui concerne votre deuxième point, sautez simplement la propriété limites et la limite par défaut sera l'infini.

À des fins de démonstration, j'ai configuré ce qui précède dans une application nodejs de travail, voir ci-dessous:

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

(1) Lorsque vous effectuez l'appel suivant, vous dites à multer de placer des fichiers téléchargés dans un répertoire appelé uploads . Donc, il créera ce répertoire pour vous si ce n'est pas déjà présent lorsque votre application démarre.

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

En ce qui concerne le cycle de vie de ce répertoire, il restera là-bas tant que vous ne le supprimez pas, et vous demandez toujours à Multer de l'utiliser comme destination. Les fichiers téléchargés sont ajoutés là-bas, de sorte que la taille de son contenu dépend de ce qui est téléchargé.

(2) En ce qui concerne la limitation de la taille du fichier, la valeur par défaut selon les docs est Infinity. Donc, il n'y a pas de limite, sauf si vous en définissez un.

Mais, ne sachant pas votre application, je recommande vivement de définir une limite, même si vous en avez besoin pour être assez élevé. L'élimination de la limite de taille peut entraîner de gros problèmes.


modifier
Si vous souhaitez supprimer le contenu de ./uploads lors de la mise en ligne d'un nouveau fichier, Node fournit un moyen de supprimer un fichier: fs.unlink . Voir aussi SO sur la suppression d'un fichier dans le nœud

Dans votre gestionnaire de téléchargement, inspectez le contenu de ./uploads et unlink tout fichier qui n'est pas le fichier utilisé dans la demande en cours. Voir req.file pour le téléchargement actuel.

Que 1) Vous pouvez décider du cycle de vie des dossiers.

  1. Si vous souhaitez stocker des fichiers sur le serveur et le récupérer à tout moment sans limite de taille de fichier, vous avez besoin d'un stockage plus important
  2. Si vous utilisez un tiers comme Amazon S3 pour le stockage, aucun point de stockage local, dès son chargement sur le serveur, vous pouvez supprimer du stockage local. Vous pouvez utiliser après Hook lorsque la réponse est envoyée.

     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) La valeur par défaut est illimitée.