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

j'utilise multer .

Question 1

quand j'ai mis l'extrait suivant dans le app.js

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

il crée un nouveau dossier sous le dossier racine, Ma question Est sur le cycle de vie de ce nouveau dossier, quand il sera supprimé? Combien la taille du dossier peut être après 100 appel?

Question 2

Si je ne veux pas limiter le fichier taille, ce que je devrais mettre dans la configuration?

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

mise à Jour

mon application est construite comme

app.le fichier js contient

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

app.use('/', routes, function (req, res, next) {
    next();
});

le fichier de route ressemble à celui qui suit

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

ci-dessous, comment mon application de noeud est structuré, peut quelqu'un s'il vous plaît conseil comment et où(quel fichier) son recommandé pour utiliser le code Raf avec l'ajout d'un dateTime au fichier que je peux ajouter le tri ...

22
demandé sur Raf 2016-01-04 14:42:42

3 réponses

je vais essayer de répondre à votre question avec un exemple réel, au moins vous pourriez apprendre quelques trucs. Si vous souhaitez supprimer tout sauf le téléchargement le plus récent, alors vous devez coder une sorte de logique pour différencier entre lequel téléchargement est récent et ceux qui sont anciens. Ci-dessous, je décris, comment je pourrais résoudre ce problème, peut-être pas parfait, mais, c'est comment je le fais.

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

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

vous ne voulez pas limiter le téléchargement de fichier, ne pas fournir de limites configs, cependant, il est recommandé de spécifier une limite de téléchargement de fichier.

vous pouvez évidemment attacher le paillasson à la d'application ou de créer une instance et passer à une route. Je préfère la seconde 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 montré ci-dessus, je ne laisse pas multer donner un nom aléatoire au fichier téléchargé. Ce que je fais, c'est, obtenir le nom du fichier, supprimer son extension et ensuite utiliser Date.now() qui me donnera l'horodatage actuel ajouté avec l'extension de fichier téléchargée. Si je fais six chargements, ils se montreront comme suit (la plupart de mes téléchargements ont été .jpg, tiré de filename).

Comment télécharger finirais (horodateurs ne diffèrent)

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

j'ai joint ci-dessus storage à une instance de multer comme suit:

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

maintenant je peux passer le upload à une route qui gère le téléchargement de fichier comme suit:

joindre télécharger sur route 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 et qu'à un moment donné vous voulez lister tous les fichiers du répertoire de téléchargement. L'itinéraire serait le suivant:

Liste tous les fichiers dans le répertoire 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);
});

vous voulez supprimer tous les fichiers dans le répertoire de téléchargement, la route serait comme suit:

supprimer tous les fichiers dans le répertoire de téléchargement

//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 manière synchrone, alors vous devez invoquer la version sync de readdir (readdirSync) et unlink (unlinkSync)

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

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

maintenant à votre point de supprimer tout sauf, le fichier téléchargé le plus récent. J'ai déjà fait de tous les noms de fichiers des horodateurs. Alors je ferais quelque chose comme ceci:

supprimer tous les fichiers sauf le plus récent (où le plus récent étant celui avec timestamp le plus récent comme 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 pas ajouté les limites dans mon exemple, mais il est recommandé. La limite par défaut est infinity et si vous ne l'incluez pas dans un environnement prod, 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, il suffit de sauter le la propriété limits et la limite par défaut sera infinity.

à des fins de démonstration, j'ai configuré ce qui précède dans une appli nodejs, 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); } );

vues/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")
7
répondu Raf 2016-01-21 23:20:45

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

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

en termes de cycle de vie de ce répertoire, il y restera aussi longtemps que vous ne l'effacerez pas, et vous demandez toujours à multer de l'utiliser comme destination. Les fichiers téléchargés y sont ajoutés, donc 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 le docs est L'infini. Il n'y a donc pas de limite à moins d'en fixer une.

mais, ne connaissant pas votre application, je vous conseille vivement de fixer une limite, même si vous avez besoin qu'elle soit assez élevée. Supprimer complètement la limite de taille peut entraîner de gros problèmes.


modifier

Si vous souhaitez supprimer le contenu de ./uploads lorsqu'un nouveau fichier est téléchargé, Nœud fournit un moyen de supprimer un fichier: fs.dissocier . Voir aussi DONC sur la suppression d'un fichier dans le noeud

dans votre gestionnaire de téléchargement, examinez le contenu de ./uploads , et unlink tout fichier qui n'est pas le fichier utilisé dans la requête actuelle. Voir req.file pour le télécharger.

1
répondu csum 2017-05-23 10:27:49

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

  1. si vous voulez stocker des fichiers sur le serveur et le récupérer à tout moment sans limite de taille de fichier , u besoin de stockage plus grand
  2. si vous utilisez un tiers comme Amazon S3 pour stocker, aucun point dans le stockage local, dès que son télé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.

0
répondu JagsSparrow 2017-05-23 12:19:22