2011-09-23 30 views

risposta

16

Ecco una soluzione semplice che utilizza le librerie fs core Nodejs combinate con la libreria asincrona. È completamente asincrono e dovrebbe funzionare proprio come il comando "du".

var fs = require('fs'), 
    path = require('path'), 
    async = require('async'); 

function readSizeRecursive(item, cb) { 
    fs.lstat(item, function(err, stats) { 
    if (!err && stats.isDirectory()) { 
     var total = stats.size; 

     fs.readdir(item, function(err, list) { 
     if (err) return cb(err); 

     async.forEach(
      list, 
      function(diritem, callback) { 
      readSizeRecursive(path.join(item, diritem), function(err, size) { 
       total += size; 
       callback(err); 
      }); 
      }, 
      function(err) { 
      cb(err, total); 
      } 
     ); 
     }); 
    } 
    else { 
     cb(err); 
    } 
    }); 
} 
+0

' path.join (item, diritem) 'è corretto? Quando lancio la funzione, restituisce 'TypeError: Can not call method 'join' of undefined' – inetbug

+1

Hai caricato il modulo' path'? – loganfsmyth

+1

No. Penso che sia meglio mostrare chiaramente il caricamento di tutti i moduli necessari nel codice. – inetbug

2

Rivedere il nodo.js File System functions. Sembra che sia possibile utilizzare una combinazione di fs.readdir(path, [cb]) e fs.stat(file, [cb]) per elencare i file in una directory e sommarne le dimensioni.

Qualcosa di simile (totalmente non testata):

var fs = require('fs'); 
fs.readdir('/path/to/dir', function(err, files) { 
    var i, totalSizeBytes=0; 
    if (err) throw err; 
    for (i=0; i<files.length; i++) { 
    fs.stat(files[i], function(err, stats) { 
     if (err) { throw err; } 
     if (stats.isFile()) { totalSizeBytes += stats.size; } 
    }); 
    } 
}); 
// Figure out how to wait for all callbacks to complete 
// e.g. by using a countdown latch, and yield total size 
// via a callback. 

Si noti che questa soluzione considera solo i file normali memorizzati direttamente nella directory di destinazione ed esegue senza ricorsione. Una soluzione ricorsiva verrebbe naturalmente controllando stats.isDirectory() e inserendo, anche se probabilmente complicherebbe la fase di "attesa del completamento".

+0

Questa soluzione ha bisogno il percorso relativo incluso nella chiamata fs.stat o avrai errori ENOENT. – citizenslave

+0

'Scopri come attendere il completamento di tutte le callback' il modo più semplice è usare una libreria basata su Promise e usare' Promise.all() ' – samvv

3

Ho testato il seguente codice e funziona perfettamente. Per favore fatemi sapere se c'è qualcosa che non capite.

var util = require('util'), 
spawn = require('child_process').spawn, 
size = spawn('du', ['-sh', '/path/to/dir']); 

size.stdout.on('data', function (data) { 
    console.log('size: ' + data); 
}); 


// --- Everything below is optional --- 

size.stderr.on('data', function (data) { 
    console.log('stderr: ' + data); 
}); 

size.on('exit', function (code) { 
    console.log('child process exited with code ' + code); 
}); 

Courtesy Link

2 ° metodo:

enter image description here

si potrebbe desiderare di riferimento API per Node.js child_process

+5

Sistema operativo Windows è una cosa ... – iOnline247

0

ES6 variante:

import path_module from 'path' 
import fs from 'fs' 

// computes a size of a filesystem folder (or a file) 
export function fs_size(path, callback) 
{ 
    fs.lstat(path, function(error, stats) 
    { 
     if (error) 
     { 
      return callback(error) 
     } 

     if (!stats.isDirectory()) 
     { 
      return callback(undefined, stats.size) 
     } 

     let total = stats.size 

     fs.readdir(path, function(error, names) 
     { 
      if (error) 
      { 
       return callback(error) 
      } 

      let left = names.length 

      if (left === 0) 
      { 
       return callback(undefined, total) 
      } 

      function done(size) 
      { 
       total += size 

       left-- 
       if (left === 0) 
       { 
        callback(undefined, total) 
       } 
      } 

      for (let name of names) 
      { 
       fs_size(path_module.join(path, name), function(error, size) 
       { 
        if (error) 
        { 
         return callback(error) 
        } 

        done(size) 
       }) 
      } 
     }) 
    }) 
} 
Problemi correlati