2011-09-23 10 views

Respuesta

16

Aquí hay una solución simple que utiliza las bibliotecas centrales Nodejs fs combinadas con la biblioteca asíncrona. Es completamente asincrónico y debería funcionar igual que el 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 (elemento, diritem) '¿es correcto? Cuando lance la función, devuelve 'TypeError: no se puede llamar al método 'join' of undefined' – inetbug

+1

¿Cargó el módulo' path'? – loganfsmyth

+1

No. Creo que es mejor mostrar claramente la carga de todos los módulos necesarios en el código. – inetbug

2

Revise node.js File System functions. Parece que puede usar una combinación de fs.readdir(path, [cb]) y fs.stat(file, [cb]) para enumerar los archivos en un directorio y sumar sus tamaños.

Algo como esto (totalmente no probado):

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. 

Tenga en cuenta que esta solución sólo tiene en cuenta los ficheros de texto almacenados directamente en el directorio de destino y realiza ninguna recursividad. Una solución recursiva vendría naturalmente al marcar stats.isDirectory() y entrar, aunque es probable que complique el paso "esperar la finalización".

+0

Esta solución necesita la ruta relativa incluido en la llamada fs.stat o te ENOENT errores. – citizenslave

+0

'Averiguar cómo esperar a que se completen todas las devoluciones de llamada' de la manera más simple es usar una biblioteca basada en Promesa y usar' Promise.all() ' – samvv

3

He probado el siguiente código y funciona perfectamente bien. Háganme saber si hay algo que no entienda.

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

segundo método:

enter image description here

Es posible que desee hacer referencia a la API Node.js para child_process

+5

El sistema operativo Windows es 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) 
       }) 
      } 
     }) 
    }) 
} 
Cuestiones relacionadas