我有很多文本文件,我想压缩它们以节省磁盘空间,然后当我需要它们时,将它们连接起来并发送给客户端。为了节省 CPU 周期,我不想解压缩/重新压缩数据。客户端也应该能够解压缩数据,结果应该加入/连接。
这是我到目前为止所做的及其结果(PHP 语言代码):
$str1 = "Hello";
$str2 = "World";
$deflate1 = gzdeflate($str1);
$deflate2 = gzdeflate($str2);
$concat = substr($deflate1, 0, -2) . $deflate2;
$inflate = gzinflate($concat);
print($inflate);
结果:
HellnWorld
如您所见,第一个字符串的最后一个字符从
o
更改为n
。
我该如何修正这个算法? (算法或 c/php/go 示例代码都可以)。
你试图用
gzdeflate()
的输出做什么是行不通的。您不能从末尾删除字节以尝试串联。您 can 只需连接由 PHP 的 gzencode()
生成的 gzip 流(不删除任何内容),然后它们就是有效的 gzip 数据。虽然我被告知gzdecode()
有一个错误,并且不会解码这样一个 gzip 成员序列。 (应该有人报告这个错误。)
您可以使用
deflate_init()
和 deflate_add()
以及适当的冲洗选项来构建兼容的、完整的压缩流。对于每个单独的流,您将使用 ZLIB_SYNC_FLUSH
,然后使用 ZLIB_FINISH
来制作一个以空的、存储的 deflate 块结尾的 deflate 流,该块以字节边界结束,然后是一个空的固定块标记为最后一个堵塞。最后一个空的固定块是两个字节。如果它从末尾删除,那么您可以在它之后连接另一个 deflate 流。连接的最后一个这样的片段应该 not 删除最后两个字节,这样整个事情就是一个正确终止的放气流。
尝试这个的时候,我又发现了一个bug。如果数据字符串为空,
deflate_add()
将不会接受 ZLIB_SYNC_FLUSH
请求。你可以整天重复调用deflate_add($def, '', ZLIB_SYNC_FLUSH);
,它什么也做不了。您需要在最后一次调用 ZLIB_SYNC_FLUSH
时使用
deflate_add()
和 一些数据。