gzdeflate () и большой объем данных
Вопрос
Я строю класс для создания ZIP-файлов в PHP. Альтернатива ZipArchive, если она не разрешена на сервере. Что-то, что можно использовать с этими бесплатными серверами.
Это уже своего рода работа, сборка ZIP-структур с помощью PHP и использование gzdeflate () для генерации сжатых данных.
Проблема в том, что gzdeflate () требует от меня загрузки всего файла в память, и я хочу, чтобы класс работал с ограничением 32 МБ памяти. В настоящее время он хранит файлы размером более 16 МБ без сжатия вообще.
Я полагаю, мне следует сжать данные в блоках, 16 МБ на 16 МБ, но я не знаю, как объединить результат двух gzdeflate ().
Я тестировал его, и похоже, что в последних 16-битных кодах ему нужна математика, вроде buff- > last16bits = (buff- > last16bits & amp; newblock- > first16bits) | 0xfffe
, работает, но не для всех примеров ...
Вопрос. Как объединить два потока DEFLATEd без его распаковки?
Решение
PHP потоковые фильтры используются для выполнения таких задач. stream_filter_append
можно использовать во время чтения или записи в потоки. Например,
$fp = fopen($path, 'r');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_READ);
Теперь fread
вернет вам дефлированные данные.
Другие советы
Это может или не может помочь. Похоже, gzwrite позволит вам записывать файлы, не загружая их полностью в память. Этот пример со страницы PHP Manual показывает, как вы можете сжать файл, используя gzwrite и fopen.
http://us.php.net/manual/en/function .gzwrite.php р>
function gzcompressfile($source,$level=false){
// $dest=$source.'.gz';
$dest='php://stdout'; // This will stream the compressed data directly to the screen.
$mode='wb'.$level;
$error=false;
if($fp_out=gzopen($dest,$mode)){
if($fp_in=fopen($source,'rb')){
while(!feof($fp_in))
gzwrite($fp_out,fread($fp_in,1024*512));
fclose($fp_in);
}
else $error=true;
gzclose($fp_out);
}
else $error=true;
if($error) return false;
else return $dest;
}