0

gzipで圧縮されたファイルを生成するPHPスクリプトを書いています。私が使用しているアプローチは、PHPで文字列を作成し、スクリプトの最後でファイルに書き出す前にその文字列をgzcompress()することです。

現在、より大きなファイルでスクリプトをテストしていて、メモリ割り当てエラーが発生しています。結果の文字列が大きくなりすぎて、一度にメモリに保持できないようです。

これを解決するために、PHPで大きな文字列が割り当てられないようにgzopen()とgzwrite()を使用しようとしました。ただし、gzwrite()で生成されたgzipファイルは、gzcompress()を使用した場合とは大きく異なります。さまざまなzipレベルで実験しましたが、役に立ちません。また、gzdeflate()を使用してみたところ、gzwrite()と同じ結果になりましたが、それでもgzcompress()とは似ていません。異なるのは最初の2バイト(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 で書き込まれた同じテキストと比較すると、圧縮ブロックのヘッダーのバイトの 1 つが 1 だけ異なっていることがわかります。最後は上記のバイトでパディングされます。結果が 1 つの deflate ブロックよりも大きい場合、差が積み重なっていきます。デフレート ストリーム ブロック ヘッダーはバイト単位でさえ整列されていないため、これを修正するのは困難です。誰もが zlib を使用するのには理由があります。その形式を書き直そうとする勇気のある人はほとんどいません。

于 2012-04-28T07:27:33.730 に答える
0

gzcompress()とgzopen()はどちらも、ブロックの圧縮にDEFLATEメソッドを使用します。しかし、それらは異なるヘッダー/トレーラーを持っています。

于 2011-12-02T09:59:10.320 に答える
0

私は一度同様の問題に遭遇しました - 基本的に、ビジネスを行うためにphpに割り当てられた十分なRAMがありませんでした。

文字列をテキストファイルとして保存し、exec() を使用して、ファイルシステムを使用してファイルを gzip しました。理想的な解決策ではありませんが、私の状況ではうまくいきました。

于 2009-07-13T02:07:26.250 に答える
0

100%確実ではありませんが、私の推測では、gzcompress は GZIP 形式を使用し、gzopen/gzwrite は ZLIB を使用します。正直なところ、この 2 つの違いはわかりませんが、GZIP が実際の圧縮に ZLIB を使用していることは知っています。

ただし、それが問題にならない可能性があります。gzopen/gzwrite で gzip ファイルを作成してから、コマンドライン gzip プログラムを使用して解凍してみてください。それが機能する場合は、gzopen/gzwrite を使用するとうまくいきます。

于 2009-07-13T16:55:55.060 に答える
0

php.ini ファイルの memory_limit パラメータを増やしてみてください

于 2009-07-13T02:32:31.500 に答える