PHP gzcompress против gzopen / gzwrite - PullRequest
0 голосов
/ 13 июля 2009

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

Сейчас я тестирую свой скрипт с большими файлами и сталкиваюсь с ошибками выделения памяти. Кажется, что строка результата становится слишком большой, чтобы удерживать ее в памяти за один раз.

Чтобы решить эту проблему, я попытался использовать gzopen () и gzwrite (), чтобы избежать выделения большой строки в PHP. Однако файл gzipped, сгенерированный с помощью gzwrite (), сильно отличается от того, когда я использую gzcompress (). Я экспериментировал с различными уровнями почтового индекса, но это не помогает. Я также попытался использовать gzdeflate () и в итоге получил те же результаты, что и gzwrite (), но все еще не похож на gzcompress (). Отличаются не только первые два байта (заголовок zlib), но и весь файл.

Чем gzcompress () отличается от этих других функций gzip в PHP? Есть ли способ, которым я могу эмулировать результаты gzcompress () при постепенном получении результата?

Ответы [ 5 ]

1 голос
/ 28 апреля 2012

Основное отличие состоит в том, что функция gzwrite инициирует zlib с опцией SYNC_FLUSH, которая добавит вывод к 4-байтовой границе (или это 2), а затем немного дополнительно (0x00 0x00 0xff 0xff 0x03).

Если вы используете их для создания Zip-файлов, помните, что утилита Mac Archive по умолчанию НЕ принимает этот формат.

Из того, что я могу сказать, SYNC_FLUSH - это опция gzip, и она не разрешена в формате PKZip / Info-ZIP, все .zip файлы и их производные получены из.

Если вы удалите небольшой файл / текст, в результате чего получите один блок deflate, и сравните его с тем же текстом, написанным с помощью gzwrite, вы увидите 2 различия, один из байтов в заголовке блока deflate отличается на 1, и конец дополняется вышеуказанными байтами. Если результат больше, чем один дефляционный блок, различия начинают накапливаться. Это трудно исправить, так как заголовки блоков потока дефлирования даже не выровнены в байтах. Есть причина, по которой все используют zlib. Мало кто достаточно смел, чтобы даже попытаться переписать этот формат!

0 голосов
/ 02 декабря 2011

И gzcompress (), и gzopen () используют метод DEFLATE для сжатия блоков. Но у них другой заголовок / трейлер.

0 голосов
/ 13 июля 2009

попробуйте увеличить параметр memory_limit в вашем файле php.ini

0 голосов
/ 13 июля 2009

Я не уверен на 100%, но я предполагаю, что gzcompress использует формат GZIP, а gzopen / gzwrite использует ZLIB. Честно говоря, я не могу сказать вам, в чем разница между ними, но я знаю, что GZIP использует ZLIB для фактического сжатия.

Вполне возможно, что все это не будет иметь значения. Попробуйте создать файл gzip с помощью gzopen / gzwrite, а затем распакуйте его с помощью программы командной строки gzip. Если это работает, то использование gzopen / gzwrite подойдет вам.

0 голосов
/ 13 июля 2009

Однажды я столкнулся с подобной проблемой - в основном не было достаточно оперативной памяти, выделенной php для ведения бизнеса.

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

...