PHP在解压缩Gzip文件时挂起?
我正在解压缩一个.gz文件,并使用php将输出放入tar。 我的代码看起来像PHP在解压缩Gzip文件时挂起?,php,gzip,pipe,tar,freeze,Php,Gzip,Pipe,Tar,Freeze,我正在解压缩一个.gz文件,并使用php将输出放入tar。 我的代码看起来像 $tar = proc_open('tar -xvf -', array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'a')), &$pipes); $datalen = filesize('archive.tar.gz'); $datapos = 0; $data = gzopen('archiv
$tar = proc_open('tar -xvf -', array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'a')), &$pipes);
$datalen = filesize('archive.tar.gz');
$datapos = 0;
$data = gzopen('archive.tar.gz', 'rb');
while (!gzeof($data))
{
$step = 512;
fwrite($pipes[0], gzread($data, $step));
$datapos += $step;
}
gzclose($data);
proc_close($tar);
它工作得很好,tar根据我的$datapos压缩文件提取了几个目录和文件,直到有一点超过一半,然后脚本将被困在fwrite$pipes。。。我等了几分钟,等待它前进
压缩档案的大小为8425648字节8.1M,未压缩档案的大小为36720640字节36M
我在这里可能做错了什么,因为我没有找到考虑类似问题的任何资源
我正在2.6.32-5-amd64 linux机器上运行带有Suhosin 0.9.32.1的php5 cli版本5.3.3-7+squeeze3。1=>阵列“管道”,“w”
您必须在标准输出上提供数据文件名。你应该清空缓冲区。我通常只是读它
您还可以将其发送到文件,这样您就不必处理它
1=>数组“文件”,“文件列表输出文件],“a”
如果你在Linux上,我喜欢这样做
1=>数组'file','dev/null','a'
[编辑:一旦输出足够多,它将等待您从标准输出中读取,这是您挂起的地方。]1=>数组'pipe','w'
您必须在标准输出上提供数据文件名。你应该清空缓冲区。我通常只是读它
您还可以将其发送到文件,这样您就不必处理它
1=>数组“文件”,“文件列表输出文件],“a”
如果你在Linux上,我喜欢这样做
1=>数组'file','dev/null','a'
[编辑:一旦输出足够多,它将等待您读取标准输出,这是您挂起的地方。]您的问题是缓冲区,如前所述。清空流缓冲区,例如:在非阻塞模式下使用$pipes[1]上的fread;或者干脆拆下v型开关 然而,我想指出,$datalen将包含数据的压缩长度,而$datapos将包含未压缩的长度,因为传递给gzread的$step是以字节为单位读取的未压缩长度。如果要使用实际未压缩的存档大小填充$datalen,请使用以下内容:
$info = shell_exec('gzip -l archive.tar.gz');
$temp = preg_split('/\s+/', $info);
$datalen = $temp[6]; // the actual uncompressed filesize
否则,$datapos总是比$datalen大。您的问题是缓冲区问题,如前所述。清空流缓冲区,例如:在非阻塞模式下使用$pipes[1]上的fread;或者干脆拆下v型开关 然而,我想指出,$datalen将包含数据的压缩长度,而$datapos将包含未压缩的长度,因为传递给gzread的$step是以字节为单位读取的未压缩长度。如果要使用实际未压缩的存档大小填充$datalen,请使用以下内容:
$info = shell_exec('gzip -l archive.tar.gz');
$temp = preg_split('/\s+/', $info);
$datalen = $temp[6]; // the actual uncompressed filesize
否则,$datapos总是大于$datalen。为什么不使用tar的z开关?@netcoder因为我想在提取大文件时为用户提供一个简单的进度反馈。为什么不使用tar的z开关呢?@netcoder因为我想提供一个简单的进度反馈在提取大文件时为用户提供反馈。或者干脆完全废弃v开关。lol,我甚至没有想过,但是是的,你也可以完全废弃v。或者干脆完全废弃v开关。lol,我甚至没有想过,但是是的,你也可以完全废弃v。