Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中将分块gzip文件写入任意输出流_Php_Zlib - Fatal编程技术网

在PHP中将分块gzip文件写入任意输出流

在PHP中将分块gzip文件写入任意输出流,php,zlib,Php,Zlib,我的原始代码执行以下操作: $data=file\u get\u contents($source); $compressed_data=gzencode($data); 文件内容($destination,$compressed\u data); 这很好,而且它似乎支持$source和$destination的许多不同值,包括内存文件系统、stdin/stdout流等 但是,大型文件必须完全加载到内存中,因此我想将其切换到分块方法 我尝试了以下方法: $in=fopen($source,'r

我的原始代码执行以下操作:

$data=file\u get\u contents($source);
$compressed_data=gzencode($data);
文件内容($destination,$compressed\u data);
这很好,而且它似乎支持
$source
$destination
的许多不同值,包括内存文件系统、stdin/stdout流等

但是,大型文件必须完全加载到内存中,因此我想将其切换到分块方法

我尝试了以下方法:

$in=fopen($source,'rb');
$out=gzopen($destination,'wb');
而(!feof($in)){
gzwrite($out,fread($in,4096));
}
但这给了我一个流包装器错误(例如):
gzopen():不能将用户空间类型的流表示为文件描述符

还尝试了以下方法:

$in=fopen($source,'rb');
$out=fopen($destination,'wb');
流过滤器附加($out,'zlib.deflate',流过滤器写入,-1);
而(!feof($in)){
fwrite($out,fread($in,4096));
}
但是结果输出似乎不是有效的GZIP(可能缺少标头?)

最后我试了一下:

$in=fopen($source,'rb');
$out=fopen('compress.zlib://'。$destination,'wb');
而(!feof($in)){
fwrite($out,fread($in,4096));
}
但是(毫不奇怪)如果
$destination
已经有一个包装器(比如
php://stdin
或上面提到的
vfs://


必须有一种方法来做到这一点,但是搜索没有找到任何例子。

我现在重新实现了GZip页眉和页脚的规范,这是在使用
stream\u filter\u append()
zlib.deflate
时唯一缺少的东西(上面的第二个解决方案)

(最小)标头由以下定义的十个字节组成:

页脚由八个字节组成:四个字节用于未压缩负载的CRC32校验和,四个字节用于负载的字节长度(模2^32)

CRC32在这里提出了一个进一步的问题,因为PHP没有提供一种在不将整个负载加载到内存中的情况下计算它的方法,这是我们试图避免的

相反,我重新实现了Mark Adler的
crc32\u combine
算法,该算法使用两个字符串的crc32校验和(以及第二个字符串的长度)来计算其串联的crc32校验和: 这允许在加载和压缩每个块时更新CRC32

1F 8B       // gzip format
08          // deflate compression
00          // flags
00 00 00 00 // four bytes for the file's mtime, zero if inapplicable or after 2038
00          // more flags
03          // operating system (03 for linux)