2

tar.gz ファイルを解凍し、出力を phpに入れています。私のコードは次のようになります

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

$dataposそれはうまく機能します(tarはいくつかのディレクトリとファイルを抽出します)(私のによると)圧縮ファイルの半分以上になるまで、スクリプトはそのfwrite($pipes...)行で永久にスタックします(私はそれが進むのを数分待ちました)。

圧縮されたアーカイブは 8425648 バイト (8.1M) の大きさで、圧縮されていないアーカイブは 36720640 バイト (36M) の大きさです。

同様の問題を考慮したリソースが見つからないので、ここで何が間違っているのでしょうか?

2.6.32-5-amd64 Linux マシンで php5-cli バージョン 5.3.3-7+squeeze3 (Suhosin 0.9.32.1 を使用) を実行しています。

4

2 に答える 2

3

1 => array('pipe', 'w')

stdout にデータ (ファイル名) を提供する tar があります。そのバッファを空にする必要があります。(普通に読んでます。)

ファイルに送信することもできるので、対処する必要はありません。

1 => array('file', '[file for filelist output]', 'a')

あなたがLinuxを使っているなら、私はやりたい

1 => array('file', '/dev/null', 'a')

[編集: 十分な出力が得られると、標準出力からの読み取りを待機します。これは、ハングアップしている場所です。]

于 2012-06-27T16:36:39.193 に答える
1

@EPBが言ったように、あなたの問題はバッファの1つです。ストリーム バッファを空にします (例:ノンブロッキング モードでfreadonを使用するか、単にスイッチを削除します)。$pipes[1]v

ただし、これ$datalenにはデータの圧縮された長さが含まれますが、圧縮されていない長さが含まれます。$dataposこれは、$step渡されたgzreadがバイト単位で読み取る圧縮されていない長さであるためです。実際の圧縮されていないアーカイブのサイズを入力する場合は$datalen、次のようにします。

$info = shell_exec('gzip -l archive.tar.gz');
$temp = preg_split('/\s+/', $info);
$datalen = $temp[6]; // the actual uncompressed filesize

$dataposそうしないと、常に より大きくなってしまいます$datalen

于 2012-06-27T16:44:00.723 に答える