所以我试图将 64MB 文件分割FileCarve.001
成 512 字节段(每个块长 512 字节)。我需要确保文件在分割成较小的文件时具有相同的数据,因此我将cat
所有文件进行标准输出并将其通过管道传输到sha256sum
(有很多文件,所以我需要使用 和 来执行此操作find
)xargs
。
当命令分割输出时,将文件分割为 512 字节段似乎会导致数据混乱split
。
$ 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/
在每次运行时清除了目录。
答案1
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(质数)字节。