【问题标题】:Get size of folder using du command使用 du 命令获取文件夹大小
【发布时间】:2019-10-29 04:38:03
【问题描述】:

我曾经在电子应用程序中使用此代码获取目录大小

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);
});

它在我的机器上工作。当我在另一台 Windows 机器上构建并运行时,它抛出 du is not Recognized as internal command like that...

  1. 为什么这只能在我的机器上工作,而不能在其他 Windows 机器上工作。
  2. 而且我也怀疑它在 linux / mac 机器上是否有效???
  3. 这个 du 命令是如何工作的??

否则有什么通用方法可以在所有三个平台和所有机器上获取目录大小。

【问题讨论】:

  • du 是一个 linux 程序,也许在 windows 10 上它以某种方式可用,但如果你安装了 cygwin 之类的东西,它也可以在 windows 上使用...
  • 我的应用程序需要在所有三个平台上运行,而不需要任何额外的依赖项,正如你所说的 cygwin ,那么有没有其他方法来获取目录大小??

标签: javascript node.js spawn du


【解决方案1】:

我知道这个问题有点老了,但最近我发现自己正在寻找一个明确而简短的答案来说明如何去做,如果它对某人有用,那么,如果它不仅消耗了几个字节。

我必须澄清一下,我不是任何方面的专家,但我喜欢学习,这就是我在寻找解决方案时学到的:

*/
First declare the needs of a Child Process and [execSync()][1]
"the method will not return until the child process has fully closed"
*/

此脚本是同步操作

//Declares the required module
const execSync = require('child_process').execSync;
//Declare the directory or file path
const target = "Absolute path to dir or file";
/*
Declare a variable or constant to store the data returned,
parse data to Number and multiplying by 1024 to get total 
bytes
*/
const size = parseInt(execSync(`du '${target}'`)) * 1024;
//Finally return or send to console, the variable or constant used for store data
return size;

使用exec或execSync可以在Unix系统中执行文件或命令,当在终端执行du 'some path'时,获取文件或目录的磁盘利用率,并再次绝对pat,因此需要使解析为整数的结果,execSync 得到一个缓冲区作为结果。

我使用模板字符串作为参数以避免编写更多代码行,因为您不必处理字符串路径中的空白问题,该方法支持这些空白。

//If executed in a terminal
du 'path to file or directory including white spaces in names'
// returns something like
125485 path to file or directory including white spaces in names

All about du command for Unix

我的母语不是英语,所以我使用翻译作为口译,对于语言错误,我深表歉意。

All about du equivalent for Windows

【讨论】:

    【解决方案2】:

    du 是一个 Linux 命令。它通常在 Windows 中不可用(不知道 Mac,抱歉)

    child_process 模块提供了产生子进程的能力。看来您只是在操作系统中执行命令。因此,要让解决方案适用于多个系统,您可以有两种选择:

    • 检查操作系统,并执行(使用 spawn)适当的系统命令,就像您现在所做的那样。这使代码保持简单
    • 或者,使用 JavaScript 代码(StackOverflow 中有许多关于如何在 node.js 中获取目录大小的问题)。我认为这将是覆盖任何操作系统而不用担心命令支持的最安全方式。

    您必须在您的 Windows 系统中安装了一些 linux 工具,但您不能指望在任何常见的 Windows 中都可以使用它们

    【讨论】:

    • 我检查了所有其他可能的方式,所有方式都需要递归读取文件夹内的文件。然后将其添加到 sum 。看起来像老派的方法。所以我选择了这个方法
    • @Ram,当然,如果你想得到一个文件夹大小,包括子文件夹,它需要递归遍历文件和目录树。 du 本身就是递归的 :-)
    【解决方案3】:

    您可以使用内置的node.js fs 软件包的stat 命令...但是,如果您执行整个驱动器,这会在内存中爆炸。最好可能坚持使用经过验证的节点之外的工具。

    https://repl.it/@CodyGeisler/GetDirectorySizeV2

    const { promisify } = require('util');
    const watch = fs.watch;
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const path = require('path');
    const { resolve } = require('path');
    
    
    const getDirectorySize = async function(dir) {
      try{
        const subdirs = (await readdir(dir));
        const files = await Promise.all(subdirs.map(async (subdir) => {
          const res = resolve(dir, subdir);
          const s = (await stat(res));
          return s.isDirectory() ? getDirectorySize(res) : (s.size);
        }));
        return files.reduce((a, f) => a+f, 0);
      }catch(e){
        console.debug('Failed to get file or directory.');
        console.debug(JSON.stringify(e.stack, null, 2));
        return 0;
      }
    };
    
    (async function main(){
      try{
        // Be careful if directory is large or size exceeds JavaScript `Number` type
        let size = await getDirectorySize("./testfolder/")
        console.log('size (bytes)',size);
      }catch(e){
        console.log('err',e);
      }
    })();
    

    【讨论】:

    • 是的,我尝试使用本机 fs 模块,当尝试获取大文件目录的大小时,它需要时间并挂起我的系统。无论如何谢谢你
    【解决方案4】:

    非常原始和同步的代码。对于产品,您必须切换到异步功能。

    const path = require('path');
    const fs = require('fs');
    
    function dirsizeSync(dirname) {
        console.log(dirname);
        let size = 0;
        try {
            fs.readdirSync(dirname)
                .map(e => path.join(dirname, e))
                .map(e => {
                    try {
                        return {
                            dirname: e,
                            stat: fs.statSync(e)
                        };
                    } catch (ex) {
                        return null;
                    }
                })
                .forEach(e => {
                    if (e) {
                        if (e.stat.isDirectory()) {
                            size += dirsizeSync(e.dirname);
                        } else if (e.stat.isFile()) {
                            size += e.stat.size;
                        }
                    }
                });
        } catch (ex) {}
        return size;
    }
    
    console.log(dirsizeSync('/tmp') + ' bytes');
    

    【讨论】:

    • 我以异步方式尝试过这种方式,但是对于大量文件,例如:嵌套文件夹中的 10,000 个文件意味着执行时间很慢,因此只有我移至该命令。无论如何谢谢。
    【解决方案5】:

    1.你机器上安装的windows可能有sysinternals du命令。它并非存在于所有 Windows 安装中。您可能更喜欢使用 windirstat.info 或类似 www.getfoldersize.com 这样更原生的东西。

    2. 由于 UNIX 和 Linux 命令用于估计文件空间使用情况,因此它应该适用于任何 UNIX 等操作系统。

    3. du 命令是用于报告文件系统磁盘空间使用情况的命令行实用程序。它可用于找出文件和文件夹的磁盘使用情况并显示占用空间的内容。它支持仅显示目录或所有文件,显示总计,以人类可读格式输出,并且可以与其他 UNIX 工具结合以输出系统上最大文件夹文件的排序列表。见:https://shapeshed.com/unix-du/

    如果您需要它在 UNIX 和非 UNIX 操作系统上工作,您应该首先检查程序用户使用的操作系统,然后根据运行的操作系统执行不同的命令。

    【讨论】:

    • 对于 windows 是否有任何命令可以在所有机器上运行。因为它可以在我的 windows 7 中运行,而不是在另一个 windows 7 中运行。无需安装其他软件包。
    • 也许您可以使用 PowerShell:ls -r | measure -s Length。或者使用 CMD powershell -noprofile -command "ls -r|measure -s Length"。但老实说,我不太确定......
    • 第二个使用 powershell 的命令可以做到这一点。但不是 ls 我可以指定目录路径
    • 我猜:powershell -noprofile -command "ls -r <DIRECTORY_PATH>|measure -s Length"
    • 请注意,您可以使用 node.js 内置包 'os' 来检查操作系统的类型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    相关资源
    最近更新 更多