2012-08-12 64 views
2

解壓縮的gzip發現這一點: https://stackoverflow.com/a/11373078/530599 - 偉大的,但與在stream_filter_append和stream_copy_to_stream

怎麼樣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); 

哪裏$src是一些網址http://.../file.gz例如200 + MB :)

加入的測試代碼的作品,但在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'); 

回答

3

PHP的流過濾器子系統令人討厭的遺漏之一是缺乏gzip過濾器。 Gzip本質上是使用deflate方法壓縮的內容。它在收縮的數據之前添加了一個2字節的頭部,然而在最後還有一個Adler-32校驗和。如果您只是將一個zlib.inflate過濾器添加到一個流中,它不會起作用。在附加過濾器之前,您必須跳過前兩個字節。

請注意,PHP版本5.2.X中的流篩選器存在嚴重錯誤。這是由於流緩衝。基本上PHP將無法通過過濾器將流中內部緩衝區中的數據傳遞給它。如果您在連接充氣過濾器之前使用fread($ handle,2)讀取gzip標頭,那麼很可能會失敗。調用fread()將導致PHP嘗試填充其緩衝區。即使調用fread()只需要兩個字節,PHP實際上可能會從物理介質中讀取更多的字節(比如說1024),以提高性能。由於上述錯誤,額外的1022字節不會被髮送到解壓縮例程。

4

嘗試gzopen這將打開用於閱讀或寫作的gzip(.gz)文件。如果文件不是壓縮文件,它會透明地讀取它,以便您可以安全地讀取非壓縮文件。

$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);