【问题标题】:uncompressing gzip with stream_filter_append and stream_copy_to_stream使用 stream_filter_append 和 stream_copy_to_stream 解压缩 gzip
【发布时间】:2012-08-09 03:10:57
【问题描述】:

发现这个: 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);

$src 是指向http://.../file.gz 的某个网址,例如 200+ Mb :)

添加了有效的测试代码,但分两步:

<?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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      PHP 的流过滤子系统中令人讨厌的遗漏之一是缺少 gzip 过滤器。 Gzip 本质上是使用 deflate 方法压缩的内容。然而,它在压缩数据之前添加了一个 2 字节的标头,并在末尾添加了一个 Adler-32 校验和。如果您只是将 zlib.inflate 过滤器添加到流中,它不会起作用。在附加过滤器之前,您必须跳过前两个字节。

      请注意,PHP 5.2.X 版中的流过滤器存在严重错误。这是由于流缓冲。基本上 PHP 将无法通过过滤器传递流的内部缓冲区中已经存在的数据。如果您在附加膨胀过滤器之前执行 fread($handle, 2) 来读取 gzip 标头,那么它很有可能会失败。调用 fread() 会导致 PHP 尝试填满其缓冲区。即使对 fread() 的调用只要求两个字节,PHP 实际上可能会从物理介质中读取更多字节(比如说 1024)以尝试提高性能。由于上述错误,额外的 1022 字节不会发送到解压缩例程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-14
        • 2012-09-25
        • 1970-01-01
        • 1970-01-01
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多