ZIP большой файл во многих вызовах, используя PHP PCL Zip

Файл 100 МБ -> 10 ZIP-звонков (10 МБ на звонок) -> 1 ZIP-файл

Я должен инициировать 10 звонков, чтобы добавить один файл размером 100 МБ в Zip-файл (скажем, 10 МБ архивирования за вызов).

Проблема в том, что у нас есть система с памятью и ограничением по времени (которая не будет обрабатывать более 10-15 МБ на вызов).

Таким образом, основная идея заключается в архивировании большого файла со многими вызовами.

Я готов предоставить больше данных, если потребуется.

2 ответа

Вы когда-нибудь пробовали PECL Zip раньше?

Просто заархивировал два файла со следующим кодом без каких-либо проблем с ограничением памяти. Ограничение по времени может быть сброшено. Моя среда: memory_limit 3MB и max_exection время 20 секунд.

<?php
set_time_limit(0);
$zip = new ZipArchive();
$zip->open('./test.zip', ZipArchive::CREATE);
$zip->addFile('./testa'); // 1.3 GB
$zip->addFile('./testb'); // 700mb
$zip->close();

Примечание: http://php.net/set_time_limit не будет работать на php < 5.4 с save_mode=on


Другим подходом может быть создание почтового индекса в фоновом режиме. Это позволяет избежать возможных проблем с memory_limit.

Вот пример: http://pastebin.com/7jBaPedb

Использование:

try {
  $t = new zip('/bin', '/tmp/test.zip');
  $t->zip();

  if ($t->waitForFinish(100))
    echo "Succes :)";
  else
    echo $t->getOutput();
} catch ($e) {
  echo $e->getMessage();
}

Вместо того, чтобы ждать окончания процесса, вы можете записать pid в базу данных и обработать файл, если он закончился...

Читая ваш вопрос, я впервые начал создавать упаковщик в виде молнии в виде кусочков, чтобы делать то, что вы просили. Он сгенерирует массив со ссылками на веб-страницу, которую нужно было открыть последовательно для создания zip-файла. Пока идея работала, я быстро понял, что она не нужна.

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

Asbjorn Grandt - один из тех, кто создал этот класс zip, который очень прост в использовании и делает то, что вам нужно.

Сначала я создал очень большой файл. Он будет размером 500 МБ с различными буквами. Этот файл является способом обратной обработки сразу, что приводит к фатальным ошибкам ограничения памяти.

<?php
$fh = fopen("largefile.txt", 'w');
fclose($fh);
$fh = fopen("largefile.txt", 'ab');
$size = 500;
while($size--) {
  $l = chr(rand(97, 122));
  fwrite($fh, str_repeat($l, 1024*1024));
}
fclose($fh);
?>

И чтобы использовать класс zip, мы бы сделали:

<?php
include('zip.php');

$zip = new Zip();
$zip->setZipFile("largefile.zip");
//the firstname is the name as it will appear inside the zip and the second is the filelocation. In my case I used the same, but you could rename the file inside the zip easily.
$zip->addLargeFile("largefile.txt", "largefile.txt");
$zip->finalize();
?>

Теперь большой zip создается за несколько секунд на моем сервере, и в результате получается файл размером 550 КБ.

Теперь, если по какой-то странной причине вам все еще нужно сделать это в нескольких веб-запросах, дайте мне знать. У меня все еще есть код, с которого я начал, чтобы сделать это.

Другие вопросы по тегам