2011-09-23 19 views

Odpowiedz

16

Oto proste rozwiązanie z użyciem podstawowych bibliotek Nodejs fs w połączeniu z biblioteką asynchroniczną. Jest w pełni asynchroniczny i powinien działać tak, jak polecenie "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 (pozycja, diritem) 'jest poprawny? Po uruchomieniu funkcji zwraca 'TypeError: Can not call method 'join' of undefined' – inetbug

+1

Czy załadowałeś moduł' path'? – loganfsmyth

+1

Nie. Myślę, że lepiej jest wyraźnie pokazać ładowanie wszystkich niezbędnych modułów w kodzie. – inetbug

2

Przejrzyj plik node.js File System functions. Wygląda na to, że możesz użyć kombinacji fs.readdir(path, [cb]) i fs.stat(file, [cb]), aby wyświetlić listę plików w katalogu i zsumować ich rozmiary.

Coś jak ten (całkowicie niesprawdzone):

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. 

Należy zauważyć, że rozwiązanie to uwzględnia jedynie zwykłe pliki zapisane bezpośrednio w folderze docelowym i nie wykonuje żadnej rekursji. Rekursywne rozwiązanie przychodzi naturalnie, sprawdzając stats.isDirectory() i wprowadzając, chociaż prawdopodobnie komplikuje krok "Oczekiwanie na zakończenie".

+0

To rozwiązanie wymaga ścieżkę względną zawarte w zaproszeniu fs.stat lub dostaniesz błędy ENOENT. – citizenslave

+0

'Sprawdź, jak poczekać na zakończenie wszystkich wywołań zwrotnych" Najprostszym sposobem jest użycie biblioteki opartej na obietnicy i użycie 'Promise.all()' – samvv

3

Przetestowałem poniższy kod i działa idealnie dobrze. Proszę dać mi znać, jeśli jest coś, czego nie rozumiesz.

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-ty metoda:

enter image description here

Może chcesz przekazać API node.js dla child_process

+5

Windows OS to rzecz ... – iOnline247

0

ES6 wariant:

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) 
       }) 
      } 
     }) 
    }) 
} 
Powiązane problemy