我有一个 1 TB 的文件。我想从字节 12345678901 读取到字节 19876543212 并将其放在具有 100 MB RAM 的机器上的标准输出上。
我可以轻松编写一个执行此操作的 perl 脚本。sysread 提供 700 MB/s(很好),但 syswrite 仅提供 30 MB/s。我想要更高效的东西,最好是每个 Unix 系统都安装的东西,并且可以以 1 GB/s 的速度交付。
我的第一个想法是:
dd if=1tb skip=12345678901 bs=1 count=$((19876543212-12345678901))
Run Code Online (Sandbox Code Playgroud)
但这效率不高。
编辑:
我不知道我是如何测量 syswrite 错误的。这提供了 3.5 GB/s:
perl -e 'sysseek(STDIN,shift,0) || die; $left = shift; \
while($read = sysread(STDIN,$buf, ($left > 32768 ? 32768 : $left))){ \
$left -= $read; syswrite(STDOUT,$buf);
}' 12345678901 $((19876543212-12345678901)) < bigfile
Run Code Online (Sandbox Code Playgroud)
并避免yes | dd bs=1024k count=10 | wc
噩梦。
split
将文件分割成多个块,这些块总共消耗相同的存储空间(消耗的磁盘空间加倍)。
ln
可以创建到其他(目标)文件的符号链接(symlink),同时不复制文件,因此不会消耗目标文件双倍的空间。
由于缺乏存储空间,是否可以通过指向大文件中特定偏移量的引用/符号方式(即虚拟地分割文件)来分割文件?
例如,给定一个 2MB 的文件,将其分成 2 个部分,其中每个部分引用大文件的 1MB(与符号链接工作原理相同),这样每个部分:
piece_1.file -> 2mb.file 1st MB
piece_2.file -> 2mb.file 2nd MB
Run Code Online (Sandbox Code Playgroud)
并且每块的存储大小远小于1MB