【问题标题】:How to get directory size in node.js without recursively going through directory?如何在 node.js 中获取目录大小而不递归遍历目录?
【发布时间】:2015-08-07 12:06:58
【问题描述】:

如何在 node.js 中获取目录的大小而不递归遍历目录中的所有子项?

例如

var fs = require('fs');
fs.statSync('path/to/dir');

会给我一个这样的对象,

{ dev: 16777220,
  mode: 16877,
  nlink: 6,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 62403939,
  size: 204,
  blocks: 0,
  atime: Mon May 25 2015 20:54:53 GMT-0400 (EDT),
  mtime: Mon May 25 2015 20:09:41 GMT-0400 (EDT),
  ctime: Mon May 25 2015 20:09:41 GMT-0400 (EDT) }

size 属性不是目录的大小,而是子目录(也就是其中的文件的总和)。

如果不递归地找到子项的大小(然后将它们相加),就没有办法获得目录的大小(包括其中包含的文件的大小)吗?

我基本上是在尝试做与du -ksh my-directory 等效的操作,但如果给定的目录真的很大(例如/),那么递归获取真正的目录大小需要永远......

【问题讨论】:

  • 我知道du -ksh / 需要很长时间,所以也许这个问题是......静音......我希望我在这里缺少一个 linuxy 的东西......
  • du 正是这样做的,所以不,你无法绕过它。
  • 据我所知,目录不会跟踪它们下面所有文件的累积大小,因此获得累积大小的唯一方法是递归和添加。这不是一个快速的操作。

标签: node.js fs


【解决方案1】:

我使用这个简单的async/await + fs Promises API (Node.js v14+) 解决方案...它不依赖于外部库或产生新进程,这很好:

const { readdir, stat } = require('fs/promises');

const dirSize = async directory => {
  const files = await readdir( directory );
  const stats = files.map( file => stat( path.join( directory, file ) ) );

  return ( await Promise.all( stats ) ).reduce( ( accumulator, { size } ) => accumulator + size, 0 );
}

用法:

const size = await dirSize( '/path/to/directory' );
console.log( size );

这不使用任何 循环构造 来递归遍历目录,尽管它是映射/归约数组。其他解决方案只是抽象 NPM 包/C 代码后面的递归,所以应该都很好......

【讨论】:

    【解决方案2】:

    fast-folder-size 使用 Windows 上的Sysinternals DU 和其他平台上内置的du 程序来快速计算文件夹大小。

    安装

    npm i fast-folder-size

    用法

    const fastFolderSize = require('fast-folder-size')
    
    fastFolderSize('.', (err, bytes) => {
      if (err) {
        throw err
      }
    
      console.log(bytes)
    })
    

    【讨论】:

      【解决方案3】:

      您可以在您的目标目录上生成一个du 命令,但正如您所说,第一次它可能会相当慢。你可能不知道du 结果似乎以某种方式被缓存:

      $ time du -sh /var
      13G /var
      du -sh /var  0.21s user 0.66s system 9% cpu 8.930 total
      $ time du -sh /var
      13G /var
      du -sh /var  0.11s user 0.34s system 98% cpu 0.464 total
      

      最初需要 8 秒,然后只需要 0.4 秒

      因此,如果您的目录不经常更改,则使用 du 可能是最简单的方法。

      另一种解决方案是将其存储在缓存层中,这样您就可以观察根目录的更改,然后计算文件夹的大小,将其存储在缓存中,并在需要时提供服务。要执行此操作,您可以使用 NodeJS 的监视功能,但您会遇到一些跨平台问题,因此像 chokidar 这样的库可能会有所帮助。

      【讨论】:

      • 更好的是,您可以使用du -s /var | cut -f1获取以字节为单位的文件夹大小
      【解决方案4】:

      您应该尝试“getFolderSize”节点模块 https://www.npmjs.com/package/get-folder-size

      用法

      getFolderSize(folder, [regexIgnorePattern], callback)
      

      例子:

      var getSize = require('get-folder-size');
      
      getSize(myFolder, function(err, size) {
        if (err) { throw err; }
      
        console.log(size + ' bytes');
        console.log((size / 1024 / 1024).toFixed(2) + ' Mb');
      });
      

      【讨论】:

      • 您好,请扩展您的答案以包含即使没有超链接也有用的解决方案。提前致谢。
      • 您发布的模块使用递归解决方案。 github.com/alessioalex/get-folder-size/blob/master/index.js#L7
      • 对于小的浅目录可能没问题。对于大的深层目录来说是可怕的。我宁愿运行一个 shell 命令并让操作系统处理它。它也没有给出磁盘大小 - 这是检查文件夹大小的常见动机。
      猜你喜欢
      • 1970-01-01
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-11
      • 2013-01-23
      • 2011-01-03
      • 2011-08-29
      相关资源
      最近更新 更多