为什么du
的输出经常与du -b
如此不同? -b
是--apparent-size --block-size=1
的简写。只使用--apparent-size
大多数时候给我相同的结果,但--block-size=1
似乎做了伎俩。我想知道输出是否正确,哪个数字是我想要的? (即实际文件大小,如果复制到另一个存储设备)
表观大小是应用程序认为在文件中的字节数。如果您决定通过FTP或HTTP发送文件,则它是通过网络传输的数据量(不包括协议头)。这也是cat theFile | wc -c
的结果,以及如果使用mmap
加载整个文件,文件占用的地址空间量。
磁盘使用量是因为您的文件占用该空间而无法用于其他内容的空间量。
在大多数情况下,表观大小小于磁盘使用量,因为磁盘使用量计算文件最后(部分)块的完整大小,而表观大小仅计算最后一个块中的数据。但是,当你有一个稀疏文件时,表观大小会更大(当你寻找文件末尾的某个地方时会创建稀疏文件,然后在那里写一些东西 - 操作系统不会创建大量填充零的块 - - 它只为您决定写入的文件部分创建一个块。
因为默认情况下du表示磁盘使用量,它与文件大小相同或更大。如下所述 - 在 - 大小
print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be
larger due to holes in (`sparse') files, internal fragmentation, indirect blocks, and the like
比较(例如)du -bm
和du -m
。
-b
设置--apparent-size --block-size=1
,但随后m
覆盖块大小为1M
。
类似于-bh
与-h
:-bh
意味着--apparent-size --block-size=1 --human-readable
,h
再次覆盖了那个块大小。
文件和文件夹的实际大小和磁盘大小
如果您遇到的表面大小几乎总是比磁盘使用高几个数量,那么这意味着您有很多(“稀疏”)文件具有内部碎片或间接块。
最小块粒度示例
让我们来看看发生了什么。
mount
告诉我,我正在/
安装的ext4分区。
stat -fc %s .
这使:
4096
现在让我们创建一些大小为1 4095 4096 4097
的文件:
#!/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
结果是:
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
所以我们看到任何低于或等于4096
的东西实际上占用了4096
字节。
然后,一旦我们越过4097
,它就会上升到8192
,这是2 * 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
得到:
8192 f
1073741825 f
相关:How to test if sparse file is supported
如果我想存储一堆小文件该怎么办?
一些可能性是:
参考书目:
在Ubuntu 16.04中测试过。