对于处理存储为.gz文件的图像(我的图像处理软件可以读取.gz文件以获得更短/更小的磁盘时间/空间)我需要检查每个文件的标题。
标题只是每个图像开头的固定大小的小结构,对于未压缩的图像,检查它非常快。为了读取压缩图像,我别无选择,只能解压缩整个文件然后检查这个标题,这当然会减慢我的程序。
是否可以读取.gz文件的第一段(比如几个K),解压缩该段并读取原始内容?我对gz的理解是,在开始一些簿记之后,压缩数据是按顺序存储的 - 这是正确的吗?
所以代替了
1.打开大文件F
2.解压缩大文件F
3.读取500字节的标题
4.重新压缩大文件F
DO
1.打开大文件F
2.从F
读取前5 K作为流A
3.将A
解压缩为流B
4.从B
我正在使用libz.so
,但我们非常感谢其他语言的解决方案!
答案 0 :(得分:11)
例如,您可以使用gzip -cd file.gz | dd ibs=1024 count=10
来解压缩前10个KiB。
gzip -cd
解压缩到标准输出。
将|
传递给dd
实用程序。
dd
实用程序将标准输入复制到标准输出。
因此dd ibs=1024
将输入块大小设置为1024字节而不是默认512.
并且count=10
仅复制10个输入块,从而停止gzip解压缩。
您希望使用标准512块大小执行gzip -cd file.gz | dd count=1
,并忽略额外的12个字节。
评论强调您可以使用gzip -cd file.gz | head -c $((1024*10))
或在此特定情况下使用gzip -cd file.gz | head -c $(512)
。原始dd
依赖于1024中的gzip解压缩的评论似乎并非如此。例如dd ibs=2 count=10
解压缩前20个字节。
答案 1 :(得分:4)
是的,这是可能的。
但是不要重新发明轮子,HDF5数据库支持不同的压缩算法(其中包含gz),你可以解决不同的问题。它与Linux和Windows兼容,并且有许多语言的包装器。它还支持并行读取和解压缩,如果您使用高压缩率,这非常有用。
下面是使用不同压缩算法从Python到PyTables的读取速度的比较:
答案 2 :(得分:0)
Deflate流可以有多个块背靠背。但是你总是可以解压缩你想要的字节数,即使它是更大块的一部分。 zlib函数gzread
需要一个长度arg,并且有多种其他方法可以解压缩特定数量的明文字节,无论整个流的长度如何。有关功能列表以及如何使用它们,请参阅the zlib
manual。
目前尚不清楚是否只想修改标题。 (你提到重新压缩整个文件,但是选项B没有重新压缩任何东西)。如果是这样,请在单独的Deflate块中写入标题,以便您可以替换该块而无需重新压缩图像的其余部分。当您调用zlib Z_FULL_FLUSH
函数来编写标题时,请使用deflate
。你可能不需要在任何地方记录标题的压缩长度;我认为可以在读取它们时计算出来以找出要替换的字节。
如果您没有修改任何内容,则重新压缩整个文件是没有意义的。您可以在找到喜欢的标题后从头开始寻找并重新启动解压缩...