为什么`du`的输出通常与`du -b`有很大不同

kni*_*ttl 26 linux filesystems filesize du

为什么输出du往往如此不同du -b-b是简写--apparent-size --block-size=1.只使用--apparent-size大部分时间给我相同的结果,但--block-size=1似乎做了伎俩.我想知道输出是否正确,哪个数字是我想要的?(即实际文件大小,如果复制到另一个存储设备)

Ken*_*oom 26

表观大小是应用程序认为在文件中的字节数.如果您决定通过FTP或HTTP发送文件,则它是通过网络传输的数据量(不包括协议头).这也是cat theFile | wc -c文件在加载整个文件时占用的地址空间的结果mmap.

磁盘使用量是因为您的文件占用该空间而无法用于其他内容的空间量.

在大多数情况下,表观大小小于磁盘使用量,因为磁盘使用量计算文件最后(部分)块的完整大小,而表观大小仅计算最后一个块中的数据.但是,当你有一个稀疏文件时,表观大小会更大(当你寻找文件末尾的某个地方时会创建稀疏文件,然后在那里写一些东西 - 操作系统不会创建大量填充零的块 - - 它只为您决定写入的文件部分创建一个块.


Cir*_*四事件 8

最小块粒度示例

让我们玩一下,看看发生了什么。

mount告诉我我位于安装在 的 ext4 分区上/

我找到它的块大小

stat -fc %s .
Run Code Online (Sandbox Code Playgroud)

这使:

4096
Run Code Online (Sandbox Code Playgroud)

现在让我们创建一些 size 的文件1 4095 4096 4097,并--block-size=1使用 的同义词来测试它们-b

#!/usr/bin/env bash
for size in 1 4095 4096 4097; do
  dd if=/dev/zero of=f bs=1 count="${size}" status=none
  echo "size     ${size}"
  echo "real     $(du --block-size=1 f)"
  echo "apparent $(du --block-size=1 --apparent-size f)"
  echo
done
Run Code Online (Sandbox Code Playgroud)

结果是:

size     1
real     4096   f
apparent 1      f

size     4095
real     4096   f
apparent 4095   f

size     4096
real     4096   f
apparent 4096   f

size     4097
real     8192   f
apparent 4097   f
Run Code Online (Sandbox Code Playgroud)

所以我们看到任何低于或等于的值实际上都会4096占用字节。4096

然后,一旦我们交叉,它就4097会上升到。81922 * 4096

很明显,磁盘总是将数据存储在4096字节块边界处。

稀疏文件会发生什么情况?

我还没有调查确切的表示是什么,但很明显确实--apparent考虑到了这一点。

这可能导致表观大小大于实际磁盘使用量。

例如:

dd seek=1G if=/dev/zero of=f bs=1 count=1 status=none
du --block-size=1 f
du --block-size=1 --apparent f
Run Code Online (Sandbox Code Playgroud)

给出:

8192    f
1073741825      f
Run Code Online (Sandbox Code Playgroud)

相关:如何测试是否支持稀疏文件

如果我想存储一堆小文件怎么办?

一些可能性是:

参考书目:

在 Ubuntu 16.04 中测试。