2

これを見つけました: https://stackoverflow.com/a/11373078/530599 - 素晴らしいですが、

どうですかstream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_*

データを解凍する別の方法を探しています。

$fp = fopen($src, 'rb');
$to = fopen($output, 'wb');

// some filtering here?
stream_copy_to_stream($fp, $to);
fclose($fp);
fclose($to);

たとえば 200+ Mb$srcへの URL はどこにありますか :)http://.../file.gz

機能するテストコードを追加しましたが、2 つのステップで行います。

<?php

    $src = 'http://is.auto.ru/catalog/catalog.xml.gz';
    $fp = fopen($src, 'rb');
    $to = fopen(dirname(__FILE__) . '/output.txt.gz', 'wb');
    stream_copy_to_stream($fp, $to);
    fclose($fp);
    fclose($to);

    copy('compress.zlib://' . dirname(__FILE__) . '/output.txt.gz', dirname(__FILE__) . '/output.txt');
4

2 に答える 2

5

gzopen読み取りまたは書き込み用に gzip (.gz) ファイルを開く方法を試してください。ファイルが圧縮されていない場合、透過的に読み取るため、gzip されていないファイルを安全に読み取ることができます。

$fp = gzopen($src, 'rb');
$to = fopen($output, 'w+b');
while (!feof($fp)) {
    fwrite($to, gzread($fp, 2048)); // writes decompressed data from $fp to $to
}

fclose($fp);
fclose($to);
于 2012-08-12T19:10:58.170 に答える
4

PHP のストリーム フィルター サブシステムの厄介な欠落の 1 つは、gzip フィルターがないことです。Gzip は、本質的に deflate メソッドを使用して圧縮されたコンテンツです。ただし、圧縮されたデータの前に 2 バイトのヘッダーが追加され、最後に Adler-32 チェックサムが追加されます。zlib.inflate フィルターをストリームに追加するだけでは、機能しません。フィルターをアタッチする前に、最初の 2 バイトをスキップする必要があります。

PHP バージョン 5.2.X のストリーム フィルタには深刻なバグがあることに注意してください。これは、ストリームのバッファリングが原因です。基本的に、PHP は、ストリームの内部バッファーに既にあるデータをフィルターを介して渡すことができません。inflate フィルターをアタッチする前に fread($handle, 2) を実行して gzip ヘッダーを読み取ると、失敗する可能性が高くなります。fread() を呼び出すと、PHP はバッファをいっぱいにしようとします。fread() の呼び出しで 2 バイトしか要求されない場合でも、PHP は実際には、パフォーマンスを向上させるために、物理メディアからさらに多くのバイト (1024 など) を読み取る可能性があります。前述のバグにより、余分な 1022 バイトが解凍ルーチンに送信されませんでした。

于 2012-08-12T23:33:10.437 に答える