$ timeout 1 cat /dev/zero > file1
$ wc -c file1
270422016 file1
$ du file1
264084 file1
问题 :
(1)270422016个空字符怎么出来就是264084字节(即258M)。
$ truncate -s 270422016 file2
$ wc -c file2
270422016 file2
$ du file2
0 file2
问题 :
(2)file2
已使用与file1
之前相同数量的空字符创建,但 的大小file2
为零,为什么?
(3) 什么是/dev/zero
做了truncate
而没有做的,反之亦然?
答案1
du
不显示以字节为单位的大小,但(在本例中)显示 1024 字节块。所以这些数字实际上是相同的 (264084 * 1024 = 270422016
)truncate
创建一个稀疏文件前提是文件系统支持这些东西/dev/zero
实际上会产生无限\0
字节,然后将其写入文件,并且写入零会像写入任何其他内容一样消耗空间。另一种生成消耗空间的文件的方法没有实际写零将使用fallocate
.
您可以使用filefrag
来获取有关此类文件的更多信息。
$ timeout 1 cat /dev/zero > file1
$ truncate -s 270422016 file2
$ fallocate -l 270422016 file3
$ filefrag -e file1 file2 file3
文件 1 ( cat /dev/zero
) 已完全写入,但在这种情况下也被证明是碎片化的:
Filesystem type is: 58465342
File size of file1 is 270422016 (66021 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 8175: 9983740.. 9991915: 8176:
1: 8176.. 32751: 11049359.. 11073934: 24576: 9991916:
2: 32752.. 54271: 11193265.. 11214784: 21520: 11073935:
3: 54272.. 62191: 11182601.. 11190520: 7920: 11214785:
4: 62192.. 70383: 11214785.. 11222976: 8192: 11190521: last,eof
file1: 5 extents found
碎片取决于有多少可用空间,以及文件系统决定从哪里开始写入文件,而不知道它最终会有多大。
文件2(truncate
)只是一个空壳,根本没有为其保留空间,它的大小仅由元数据指示,而不是由物理范围指示。
File size of file2 is 270422016 (66021 blocks of 4096 bytes)
file2: 0 extents found
文件 3 ( fallocate
) 已分配,但标记为未写入。因此,物理空间是为其保留的,甚至是未碎片的(因为文件系统事先被告知了大小)。读取该文件将导致零,即使物理上该地址可能存储有不同的数据。这是因为即时文件分配仅保留空间,但不会覆盖磁盘上的数据。
File size of file3 is 270422016 (66021 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 66020: 10983338.. 11049358: 66021: last,unwritten,eof
file3: 1 extent found