Disk-Usage

從 /dev/zero 寫入文件和截斷文件之間的區別

  • May 12, 2019
$ 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已經創建了與 has 相同數量的空字元file1,但大小file2為零,為什麼?

(3)什麼沒有/dev/zero做,truncate反之亦然?

  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

引用自:https://unix.stackexchange.com/questions/518488