2011-09-23 384 views

回答

16

這是一個簡單的解決方案,它使用核心Nodejs fs庫與異步庫結合使用。它完全異步,應該像'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)'是正確的?當我啓動函數時,它返回'TypeError:不能調用未定義的方法'join' – inetbug

+1

你加載了'path'模塊嗎? – loganfsmyth

+1

不,我認爲更好地清楚地顯示代碼中加載所有必要的模塊。 – inetbug

2

查看node.js File System functions。看起來您可以使用fs.readdir(path, [cb])fs.stat(file, [cb])的組合來列出目錄中的文件並對它們的大小進行求和。

像這樣(沒有經過測試):

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. 

請注意,此解決方案只考慮直接存儲在目標目錄中的純文本文件,並執行沒有遞歸。通過檢查stats.isDirectory()並進入,自然會產生遞歸解決方案,儘管它可能使「等待完成」步驟複雜化。

+0

這種解決方案需要包含在fs.stat調用的相對路徑,否則你會得到ENOENT錯誤。 – citizenslave

+0

'找出如何等待所有回調完成'最簡單的方法是使用基於Promise的庫並使用'Promise.all()' – samvv

3

我測試了下面的代碼,它工作得很好。 請讓我知道,如果有什麼你不明白的。

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

第二個方法:

enter image description here

您可能要參考Node.js的API爲child_process

+5

Windows操作系統是一件... – iOnline247

0

ES6變種:

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) 
       }) 
      } 
     }) 
    }) 
} 
相關問題