uncompressing gzip with stream_filter_append and s

2019-07-14 05:11发布

Found this: https://stackoverflow.com/a/11373078/530599 - great, but

how about stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_*

Looking for another way to uncompress data.

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

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

Where $src is some url to http://.../file.gz for example 200+ Mb :)

Added test-code that works, but in 2 steps:

<?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');

标签: php stream zlib
2条回答
对你真心纯属浪费
2楼-- · 2019-07-14 05:44

Try gzopen which opens a gzip (.gz) file for reading or writing. If the file is not compress, it transparently reads it so you can safely read a non-gzipped file.

$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);
查看更多
男人必须洒脱
3楼-- · 2019-07-14 05:46

One of the annoying omissions in PHP's stream filter subsystem is the lack of a gzip filter. Gzip is essentially contents compressed using the deflate method. It adds a 2-byte header before the deflated data, however, and a Adler-32 checksum at the end. If you just add an zlib.inflate filter to a stream, it's not going to work. You have to skip the first two bytes before attaching the filter.

Note that there's a serious bug with stream filters in PHP version 5.2.X. It's due to stream buffering. Basically PHP would fail to pass data already in the stream's internal buffer through the filter. If you do a fread($handle, 2) to read the gzip header before attaching the inflate filter, there's a good chance that it's going to fail. A call to fread() would cause PHP to try to fill up the its buffer. Even if the call to fread() asks for only two bytes, PHP might actually read many more bytes (let say 1024) from the physical medium in an attempt to improve performance. Due to the aforementioned bug, the extra 1022 bytes would not get send to the decompression routine.

查看更多
登录 后发表回答