0

我正在编写一个生成 gzip 文件的 PHP 脚本。我一直在使用的方法是在 PHP 中构建一个字符串,然后 gzcompress() 将该字符串写入脚本末尾的文件中。

现在我正在用更大的文件测试我的脚本并遇到内存分配错误。结果字符串似乎变得太大而无法一次保存在内存中。

为了解决这个问题,我尝试使用 gzopen() 和 gzwrite() 来避免在 PHP 中分配大字符串。但是,使用 gzwrite() 生成的 gzip 压缩文件与我使用 gzcompress() 时非常不同。我尝试了不同的拉链级别,但没有帮助。我也尝试过使用 gzdeflate() 并最终得到与 gzwrite() 相同的结果,但仍然与 gzcompress() 不同。不同的不仅仅是前两个字节(zlib 头),而是整个文件。

gzcompress() 与 PHP 中的其他 gzip 函数有何不同?有没有一种方法可以在逐步产生结果的同时模拟 gzcompress() 的结果?

4

5 回答 5

1

主要区别在于 gzwrite 函数使用 SYNC_FLUSH 选项启动 zlib,这会将输出填充到 4 字节边界(或者是 2),然后再增加一点(0x00 0x00 0xff 0xff 0x03)。

如果您使用它们来创建 Zip 文件,请注意默认的 Mac 存档实用程序不接受这种格式。

据我所知,SYNC_FLUSH 是一个 gzip 选项,不允许在 PKZip/Info-ZIP 格式中使用,所有 .zip 文件及其衍生文件都来自。

如果你对一个小文件/文本进行放气,产生一个放气块,并将其与用 gzwrite 编写的相同文本进行比较,你会看到 2 个差异,放气块的标题中的一个字节相差 1,最后用上述字节填充。如果结果大于一个放气块,则差异开始堆积。很难解决这个问题,因为 deflate 流块头甚至不是字节对齐的。每个人都使用 zlib 是有原因的。很少有人敢于尝试重写这种格式!

于 2012-04-28T07:27:33.730 回答
0

我曾经遇到过类似的问题 - 基本上没有足够的 ram 分配给 php 来做这项业务。

我最终将字符串保存为文本文件,然后使用 exec() 使用文件系统压缩文件。它不是一个理想的解决方案,但它适用于我的情况。

于 2009-07-13T02:07:26.250 回答
0

尝试增加 php.ini 文件中的 memory_limit 参数

于 2009-07-13T02:32:31.500 回答
0

我不是 100% 确定,但我的猜测是 gzcompress 使用 GZIP 格式,而 gzopen/gzwrite 使用 ZLIB。老实说,我不能告诉你两者之间的区别是什么,但我知道 GZIP 使用 ZLIB 进行实际压缩。

不过,这些都可能无关紧要。尝试使用 gzopen/gzwrite 创建一个 gzip 文件,然后使用命令行 gzip 程序解压缩它。如果它有效,那么使用 gzopen/gzwrite 将为您工作。

于 2009-07-13T16:55:55.060 回答
0

gzcompress() 和 gzopen() 都使用 DEFLATE 方法来压缩块。但他们有不同的标题/拖车。

于 2011-12-02T09:59:10.320 回答