Распакуйте большие файлы с помощью gzip в PHP - PullRequest
11 голосов
/ 04 августа 2009

Я использую простую функцию разархивирования (как показано ниже) для своих файлов, поэтому мне не нужно разархивировать файлы вручную перед дальнейшей обработкой.

function uncompress($srcName, $dstName) {
    $string = implode("", gzfile($srcName));
    $fp = fopen($dstName, "w");
    fwrite($fp, $string, strlen($string));
    fclose($fp);
} 

Проблема в том, что если файл gzip имеет большой размер (например, 50 МБ), то для распаковки требуется большое количество оперативной памяти.

Вопрос: могу ли я разобрать файл gzipped по частям и все же получить правильный результат? Или есть другой лучший способ справиться с проблемой извлечения больших файлов gzip (даже если это займет несколько секунд больше)?

Ответы [ 4 ]

43 голосов
/ 05 августа 2009

gzfile () - это удобный метод, который вызывает gzopen, gzread и gzclose.

Итак, да, вы можете вручную выполнить gzopen и распаковать файл кусками.

Это распакует файл в блоки по 4 КБ:

function uncompress($srcName, $dstName) {
    $sfp = gzopen($srcName, "rb");
    $fp = fopen($dstName, "w");

    while (!gzeof($sfp)) {
        $string = gzread($sfp, 4096);
        fwrite($fp, $string, strlen($string));
    }
    gzclose($sfp);
    fclose($fp);
}
1 голос
/ 05 августа 2009

Если вы находитесь на хосте Linux, обладаете необходимыми привилегиями для запуска команд и установлена ​​команда gzip, вы можете попробовать вызвать ее с помощью чего-то вроде shell_exec

Я думаю, что-то вроде этого подойдет:

shell_exec('gzip -d your_file.gz');

Таким образом, файл не будет разархивирован PHP.


В качестве обозначения:

  • Позаботьтесь о том, откуда запускается команда (не используйте swith, чтобы сказать «распаковать в что каталог»)
  • Возможно, вы захотите взглянуть и на escapeshellarg; -)
1 голос
/ 05 августа 2009

попробуй с

function uncompress($srcName, $dstName) {
    $fp = fopen($dstName, "w");
    fwrite($fp, implode("", gzfile($srcName)));
    fclose($fp);
}

Параметр длины $ является необязательным.

0 голосов
/ 16 ноября 2016

Как упоминалось maliayas , это может привести к ошибке. Я неожиданно выпал из цикла while, но файл gz был успешно распакован. Весь код выглядит так и работает лучше для меня:

function gzDecompressFile($srcName, $dstName) { 
    $error = false; 

    if( $file = gzopen($srcName, 'rb') ) { // open gz file

        $out_file = fopen($dstName, 'wb'); // open destination file

        while (($string = gzread($file, 4096)) != '') { // read 4kb at a time   
            if( !fwrite($out_file, $string) ) { // check if writing was successful
                 $error = true;
            }   
        }

        // close files
        fclose($out_file);
        gzclose($file);     

    } else {
        $error = true;
    }

    if ($error)
        return false; 
    else
        return true; 
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...