获取磁盘上目录大小和大小的最快方法

时间:2011-09-23 19:20:57

标签: windows linux bash

我最近answered提到了一个类似的问题,但我现在要做的是使用bash模拟Windows“目录 - >右击 - >属性”功能(见图)

enter image description here

我能够使用此命令以字节为单位重现大小:之类的内容:

echo $(find . -type f -printf "%s+") | sed 's/+$//g' | bc

这是非常快但是有可能获得更快的信息(比查找)或更快地完成数学(比bc)? 另外,我将使用du -sb命令模拟磁盘大小:,可能还需要另外几个find来计算文件和目录并模拟包含:< / strong> line。

有没有更好的方法来模仿这样的结果?

2 个答案:

答案 0 :(得分:2)

假设cygwin:

cd /cygdrive/c

printf "Size: %s", $( du --apparent-size -sh )
printf "Size on disk: %s", $( du  -sh )
find . -printf "%y\n" | awk '
  $1 == "d" {dirs++} 
  END {printf("Contains: %d files, %d folders\n", NR-dirs, dirs)}
'

答案 1 :(得分:1)

我刚刚根据nftw(1)编写了一个快速而又脏的工具。

该实用程序基本上只是手册页示例,添加了一些统计信息。

功能

我选择了

  • 留在单一装载点
  • 不遵循符号链接(为简单起见,因为它通常是你想要的)
  • 请注意,它仍然会计算符号链接的大小:)
  • 它显示了明显的大小(文件的长度)以及磁盘上的大小(已分配的块)。

测试,速度

我在我的盒子上测试了二进制文件(/ tmp / test):

# clear page, dentry and attribute caches
echo 3> /proc/sys/vm/drop_caches 
time /tmp/test /

输出

Total size: 28433001733
In 878794 files and 87047 directories (73318 symlinks and 0 inaccessible directories)
Size on disk 59942192 * 512b = 30690402304

real    0m2.066s
user    0m0.140s
sys 0m1.910s

我没有比较你的工具,但看起来确实很快。也许您可以获取源代码并构建自己的版本以获得最大速度?

测试稀疏文件是否实际上已正确报告:

mkdir sparse
dd bs=1M seek=1024 count=0 of=sparse/file.raw
ls -l sparse/
./test sparse/

输出:

total 0
-rw-r--r-- 1 sehe sehe 1073741824 2011-09-23 22:59 file.raw

Total size: 1073741884
In 1 files and 1 directories (0 symlinks and 0 inaccessible directories)
Size on disk 0 * 512b = 0

代码

#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

static uintmax_t total        = 0ul;
static uintmax_t files        = 0ul;
static uintmax_t directories  = 0ul;
static uintmax_t symlinks     = 0ul;
static uintmax_t inaccessible = 0ul;
static uintmax_t blocks512    = 0ul;

static int
display_info(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf)
{
    switch(tflag)
    {
        case FTW_D:
        case FTW_DP:  directories++;  break;
        case FTW_NS:
        case FTW_SL:
        case FTW_SLN: symlinks++;     break;
        case FTW_DNR: inaccessible++; break;
        case FTW_F:   files++;        break;
    }
    total += sb->st_size;
    blocks512 += sb->st_blocks;
    return 0; /* To tell nftw() to continue */
}

int
main(int argc, char *argv[])
{
    int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS;

    if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags) == -1)
    {
        perror("nftw");
        exit(EXIT_FAILURE);
    }

    printf("Total size: %7jd\n", total);
    printf("In %jd files and %jd directories (%jd symlinks and %jd inaccessible directories)\n", files, directories, symlinks, inaccessible);
    printf("Size on disk %jd * 512b = %jd\n", blocks512, blocks512<<9);

    exit(EXIT_SUCCESS);
}

编译......

gcc test.c -o test