Find

將一個小文件拆分為 512 字節段會改變它,但將其拆分為 1k 段不會

  • November 10, 2021

所以我試圖將一個 64MB 的文件FileCarve.001分成 512 字節的段(每個塊長 512 字節)。我需要確保文件在拆分為較小的文件時具有相同的數據,因此我cat將所有文件標準輸出並將其輸入sha256sum(有很多文件,所以我需要使用findand來執行此操作xargs)。

當輸出被split命令拆分時,將文件拆分為 512 字節段似乎會使數據出現亂碼。

$ dd if=FileCarve.001 bs=512 | split -b512 - splits/img
131072+0 records in
131072+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 4.10824 s, 16.3 MB/s
$ sha256sum FileCarve.001 
3e64100044099b10060f5ca3194d4d60414941c7cb26437330aba532852a60cd  FileCarve.001
$ find splits/ -type f -print0 | xargs -0 cat | sha256sum
25b37f28204895e5d0b1cb160c5fa599d15188baf7e529ccc92a10fdb3f0515a  -

但是將文件分成 1 KB 段(1000 字節)似乎工作得很好。

$ dd if=FileCarve.001 bs=512 | split -b1k - splits/img
131072+0 records in
131072+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 2.06029 s, 32.6 MB/s
$ sha256sum FileCarve.001 
3e64100044099b10060f5ca3194d4d60414941c7cb26437330aba532852a60cd  FileCarve.001
$ find splits/ -type f -print0 | xargs -0 cat | sha256sum
3e64100044099b10060f5ca3194d4d60414941c7cb26437330aba532852a60cd  -

為什麼它們不同?關於塊在儲存設備上的工作方式,我有什麼不明白的地方嗎?

回應評論:我確實split/在每次執行時都清除了目錄。

處理文件的順序find是不確定的。它可能與底層系統呼叫給出的順序相同,這可能取決於底層文件系統結構並且可以基本上是隨機的。一些實現可能會以某種方式處理列表,但不要期望它會被排序。

讓我們嘗試使用較小的文件。cat frag*重現正確的文件,因為 shell glob 確實對文件名進行了排序:

$ split -b512 orig.bin frag
$ cat frag* > new.bin
$ sha256sum orig.bin new.bin 
8d12b42623eeefee872f123bd0dc85d535b00df4d42e865f993c40f7bfc92b1e  orig.bin
8d12b42623eeefee872f123bd0dc85d535b00df4d42e865f993c40f7bfc92b1e  new.bin

find沒有,所以我們得到一個不同的文件:

$ find . -name 'frag*' -exec cat {} + > second.bin
$ sha256sum second.bin 
821325739ca65d1cb568ecf3a16bd2e01ac4eef1419b4d714834fab07d2f135c  second.bin

只是執行find列印名稱就很好地揭示了這一點:

$ find . -name 'frag*' |head -5
./fragzbgv
./fragzbmg
./fragvt
./fragyd
./fragzayc

那是在 Linux 和 ext4 上。我認為它使用某種散列和樹來儲存文件名,從而產生一個隨機的順序。在 tmpfs 上,我以相反的創建順序獲得了列表,這不是隨機的,但仍然會搞砸這種情況。

顯式排序文件名列表應該有幫助:

$ find . -name 'frag*' -print0 | sort -z | xargs -0 cat > third.bin
$ sha256sum third.bin 
8d12b42623eeefee872f123bd0dc85d535b00df4d42e865f993c40f7bfc92b1e  third.bin

它對你有用 1k 塊的事實可能是一個意外……


順便說一句,我不確定您為什麼要在dd bs=512那裡使用輸入,而不是直接cat提供split文件名。所做的事情dd是使用特定的塊大小進行讀寫,但是之間的管道ddsort保存塊大小,它只是一個字節流,文件系統真的不應該關心你用來讀取文件的塊大小,是它是 512 (2^8) 或 521 (素數) 字節。

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