Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.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_Gzip_Pipe_Tar_Freeze - Fatal编程技术网

PHP在解压缩Gzip文件时挂起?

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

我正在解压缩一个.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('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。