Пошаговое сжатие для больших файлов в Stack Overflow

Создание архивированных данных bzip2 в PHP очень легко благодаря его реализации в bzcompress. В моем настоящем приложении я не могу просто прочитать входной файл в строку и затем вызвать bzcompress или же bzwrite, Документация PHP не дает понять, являются ли последовательные вызовы bzwrite При относительно небольших объемах данных будет получен тот же результат, что и при сжатии всего файла одним махом. Я имею в виду что-то вроде

$data = file_get_contents('/path/to/bigfile');
$cdata = bzcompress($data);

Я попробовал частичную bzcompression, используя процедуры, показанные ниже

function makeBZFile($infile,$outfile)
{
$fp = fopen($infile,'r');
$bz = bzopen($outfile,'w');
while (!feof($fp))
{
$bytes = fread($fp,10240);
bzwrite($bz,$bytes);
}
bzclose($bz);
fclose($fp);
}

function unmakeBZFile($infile,$outfile)
{
$bz = bzopen($infile,'r');
while (!feof($bz))
{
$str = bzread($bz,10240);
file_put_contents($outfile,$str,FILE_APPEND);
}
}

set_time_limit(1200);
makeBZFile('/tmp/test.rnd','/tmp/test.bz');
unmakeBZFile('/tmp/test.bz','/tmp/btest.rnd');

Чтобы проверить этот код, я сделал две вещи

  • я использовал makeBZFile а также unmakeBZFile сжать, а затем распаковать базу данных SQLite — это то, что мне нужно сделать в конце концов.
  • Я создал 50 МБ, заполненный случайными данными dd if=/dev/urandom of='/tmp.test.rnd bs=50M count=1

В обоих случаях я выполнил diff original.file decompressed.file и обнаружил, что оба были идентичны.

Все очень хорошо, но мне не понятно, почему это работает. Документы PHP утверждают, что bzread(bzpointer,length) читает максимум length байты несжатое данные. Если мой код ниже, это потому, что я заставляю bzwite а также bzread размер до 10240 байт.

То, что я не могу видеть, это просто как bzread умеет доставать lenth байты несжатое данные. Я проверил формат файла bzip2. Я не вижу, что там есть что-то, что помогает легко определить длину несжатых данных для фрагмента файла .bz.

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

Я был бы очень признателен за несколько объяснений здесь.

6

Решение

Чтобы понять, как декомпрессия получает длину в байтах, вы должны сначала понять сжатие. Кажется, что вы ничего не знаете о сжатии algorigthim.

Критическим алгоритмом BZIP2 является Burrows Wheeler transformation (BWT), который преобразует исходные данные в подходящую форму для последующего кодирования. Текущая версия применяет Huffman code, Алгоритм сжатия обрабатывает данные в блоках, полностью независимых от каждого блока. Размеры блоков могут быть установлены в диапазоне от 1 до 9 (от 100 000 до 900 000 байт).

Первые два символа сжатой строки начинаются с буквы «BZ», а затем используются 1 байт для используемого алгоритма. После этого сразу следует определение размера блока, действительного для всего файла (h1, h2, h3 в h9). Параметр указывает размер блока в единицах от 1 до 9 (100 000–900 000 байт).

Фактические исходные данные хранятся в блоках в соответствии с выбранным размером и будут индивидуально защищены контрольной суммой CRC32. Кроме того, 48-битный идентификатор вводит каждый блок. Эта блочная структура позволяет частично восстановить поврежденные файлы.

Gzip и bzip2 функционально эквивалентны. Одним из преимуществ GZIP является то, что он может сжимать поток, последовательность, в которой вы не можете смотреть назад. Это делает его официальным компрессором потоков http. Спецификация формата сжатых данных GZZIP DEFLATE RFC 1951 и Спецификация формата файлов GUNZIP RFC 1952 являются опубликованными документами.

GZIP объяснил

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]