2014-09-10 13 views
5

Supponiamo di avere una directory che contiene file 100K + o addirittura 500k +. Voglio leggere la directory con fs.readdir, ma non è in streaming asincrono. Qualcuno mi dice che la memoria di uso asincrono prima di aver letto l'intero elenco di file.come leggere la directory di lettura in node.js?

Quindi qual è la soluzione? Voglio leggere l'approccio del flusso. Posso?

+1

prima di credere alle persone quando fanno quelle affermazioni: ci hai provato? Inoltre: una directory con file 100k o 500k è pazzesca, non dovresti avere i dati organizzati in questo modo. Non puoi nemmeno 'rm' che molti file. –

+0

@ Mike'Pomax'Kamermans, guarda prima: "Ho appena testato con i file 700K nella directory. Richiede solo 21 MB di memoria per caricare questo elenco di nomi di file". cosa succede se ho 1M o 10 milioni di file nella directory? – raitucarp

+1

il tuo filesystem non è un database. Un milione di file in una directory è pazzesco e invece di trovare una soluzione di codice è necessario innanzitutto organizzare meglio i dati, come buona pratica. –

risposta

7

Nei computer moderni che attraversano una directory con file 500K non è nulla. Quando si usa il comando fs.readdir in modo asincrono in Node.js, ciò che fa è semplicemente leggere un elenco di nomi di file nella directory specificata. Non legge i contenuti dei file. Ho appena testato con i file 700K nella directory. Occorrono solo 21 MB di memoria per caricare questo elenco di nomi di file.

Una volta caricato questo elenco di nomi di file, li si attraversa uno ad uno o in parallelo impostando un limite per la concorrenza e si possono facilmente consumare tutti. Esempio:

var async = require('async'), 
    fs = require('fs'), 
    path = require('path'), 
    parentDir = '/home/user'; 

async.waterfall([ 
    function (cb) { 
     fs.readdir(parentDir, cb); 
    }, 
    function (files, cb) { 
     // `files` is just an array of file names, not full path. 

     // Consume 10 files in parallel. 
     async.eachLimit(files, 10, function (filename, done) { 
      var filePath = path.join(parentDir, filename); 

      // Do with this files whatever you want. 
      // Then don't forget to call `done()`. 
      done(); 
     }, cb); 
    } 
], function (err) { 
    err && console.trace(err); 

    console.log('Done'); 
}); 
+0

sì, in realtà, non voglio leggere il contenuto dei file, ma elencando il nome del file in dir .. > Sono necessari solo 21 MB di memoria per caricare questo elenco di nomi di file. questo è il problema, voglio usare l'approccio stream – raitucarp

+2

Suggerirei di cambiare la struttura delle directory se vuoi salvare milioni di file. In alternativa, usa un database di qualche tipo. Se vuoi ancora attenersi alla tua idea originale, ti suggerisco di dare un'occhiata a https://github.com/oleics/node-filewalker. Potrebbe fornire quello che stai cercando. Sotto il cofano fa la stessa logica, cioè legge comunque l'elenco dei file dell'intera directory nella memoria. A meno che non si acceda manualmente al disco rigido e si provi a leggere la directory che elenca blocco per blocco, in Node.js non ci sono altri modi per fare ciò di cui sono a conoscenza. – Eye

+0

@Eye In che modo node-filewalker risolve il problema? –

Problemi correlati