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

时间:2022-11-11 11:48:18

I recently answered to a similar question but what I'd like to do now is to emulate using bash the Windows "Directory --> right click --> Properties" function (see fig.).

我最近回答了一个类似的问题,但我现在想做的是模拟使用bash“目录——>右键单击——> Properties”函数(见图)。

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

I was able to reproduce something like the Size: in bytes using this command:

我能够复制类似大小的东西:使用这个命令的字节:

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

which is quite fast but is it possible to get info faster (than find) or do the math faster (than bc)? In addition I would use the du -sb command to emulate the Size on Disk: and probably another couple of find to count files and directory and emulate the Contains: line.

这是相当快的,但有可能获得信息比发现更快或做计算比bc快吗?此外,我还将使用du -sb命令来模拟磁盘上的大小:可能还需要另外两个查找来计算文件和目录,并模拟Contains: line。

Are there better ways to emulate such results?

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

2 个解决方案

#1


2  

Assuming cygwin:

假设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)}
'

#2


1  

I just wrote a quick and dirty utility based on nftw(1).

我刚写了一个基于nftw(1)的快速和肮脏的实用程序。

The utility is basically just the manpage sample, with some stats added.

该实用程序基本上就是manpage示例,并添加了一些统计数据。

Functional

I opted to

我选择

  • stay within a single mountpoint
  • 保持在一个点上
  • not follow symlinks (for simplicity and because it is usually what you want)
  • 不要遵循符号链接(为了简单,因为它通常是您想要的)
  • note that it will still count the size of the symlinks themselves :)
  • 请注意,它仍然会计算符号链接本身的大小:)
  • it shows apparent size (the length of a file) as well as the size on disk (allocated blocks).
  • 它显示了明显的大小(文件的长度)以及磁盘上的大小(分配的块)。

Tests, speed

I tested the binary (/tmp/test) on my box:

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

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

output

输出

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

I haven't compared to your tooling, but it does seem rather quick. Perhaps you can take the source and build your own version for maximum speed?

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

To test whether sparse files were in fact correctly reported:

测试稀疏文件是否被正确报告:

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

Output:

输出:

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

Code

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

Compile with...

编译与…

gcc test.c -o test

#1


2  

Assuming cygwin:

假设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)}
'

#2


1  

I just wrote a quick and dirty utility based on nftw(1).

我刚写了一个基于nftw(1)的快速和肮脏的实用程序。

The utility is basically just the manpage sample, with some stats added.

该实用程序基本上就是manpage示例,并添加了一些统计数据。

Functional

I opted to

我选择

  • stay within a single mountpoint
  • 保持在一个点上
  • not follow symlinks (for simplicity and because it is usually what you want)
  • 不要遵循符号链接(为了简单,因为它通常是您想要的)
  • note that it will still count the size of the symlinks themselves :)
  • 请注意,它仍然会计算符号链接本身的大小:)
  • it shows apparent size (the length of a file) as well as the size on disk (allocated blocks).
  • 它显示了明显的大小(文件的长度)以及磁盘上的大小(分配的块)。

Tests, speed

I tested the binary (/tmp/test) on my box:

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

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

output

输出

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

I haven't compared to your tooling, but it does seem rather quick. Perhaps you can take the source and build your own version for maximum speed?

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

To test whether sparse files were in fact correctly reported:

测试稀疏文件是否被正确报告:

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

Output:

输出:

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

Code

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

Compile with...

编译与…

gcc test.c -o test