將一個小文件拆分為 512 字節段會改變它,但將其拆分為 1k 段不會
所以我試圖將一個 64MB 的文件
FileCarve.001
分成 512 字節的段(每個塊長 512 字節)。我需要確保文件在拆分為較小的文件時具有相同的數據,因此我cat
將所有文件標準輸出並將其輸入sha256sum
(有很多文件,所以我需要使用find
and來執行此操作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
是使用特定的塊大小進行讀寫,但是之間的管道dd
不sort
保存塊大小,它只是一個字節流,文件系統真的不應該關心你用來讀取文件的塊大小,是它是 512 (2^8) 或 521 (素數) 字節。