如何在 node.js 中获取目录大小而不递归遍历目录?
Posted
技术标签:
【中文标题】如何在 node.js 中获取目录大小而不递归遍历目录?【英文标题】:How to get directory size in node.js without recursively going through directory? 【发布时间】: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
正是这样做的,所以不,你无法绕过它。
据我所知,目录不会跟踪它们下面所有文件的累积大小,因此获得累积大小的唯一方法是递归和添加。这不是一个快速的操作。
【参考方案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 命令并让操作系统处理它。它也没有给出磁盘大小 - 这是检查文件夹大小的常见动机。以上是关于如何在 node.js 中获取目录大小而不递归遍历目录?的主要内容,如果未能解决你的问题,请参考以下文章
javascript [node.js 8+]递归获取目录中的所有文件