从 /dev/zero 写入文件和截断之间的区别

从 /dev/zero 写入文件和截断之间的区别
$ 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

  1. du不显示以字节为单位的大小,但(在本例中)显示 1024 字节块。所以这些数字实际上是相同的 ( 264084 * 1024 = 270422016)

  2. truncate创建一个稀疏文件前提是文件系统支持这些东西

  3. /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

相关内容