Xpoint
   [напомнить пароль]

Создание архива с большим количеством файлов и вложенных папок

Метки: [без меток]
2009-11-06 03:28:48 [обр] tcolonel[досье]

Доброго времени суток, подскажите как с помощью PHP создавать архивы с большим количеством файлов и подпапок?

Есть код:

$archive_dir = "/home/.../backup/";
$src_dir = "/home/.../.../main/public_html/";
$zipfile = $archive_dir . "backup_" . date('j_m_Y_h_m_s') . ".zip";
$zip = new ZipArchive();
$zip->open($zipfile, ZipArchive::CREATE);
$dirName = $src_dir;
if(!is_dir($dirName)) {throw new Exception('Directory ' . $dirName . ' does not exist');}
$dirName = realpath($dirName);
if(substr($dirName, -1) != '/') {$dirName .= '/';}
$dirStack = array($dirName);
$cutFrom = strrpos(substr($dirName, 0, -1), '/')+1;
while(!empty($dirStack))
{
 $currentDir = array_pop($dirStack);
 $filesToAdd = array();
 $dir = dir($currentDir);
 while(false !== ($node = $dir->read()))
 {
  if(($node == '..') || ($node == '.')) {continue;}
  if(is_dir($currentDir . $node)) {array_push($dirStack, $currentDir . $node . '/');}
  if(is_file($currentDir . $node)) {$filesToAdd[] = $node;}
 }
 $localDir = substr($currentDir, $cutFrom);
 $zip->addEmptyDir($localDir);
 foreach($filesToAdd as $file) {$zip->addFile($currentDir . $file, $localDir . $file);}
}
$zip->close();

при малом количестве файлов и папок, подпапок - код работает.
Есть класс:

class ZipFolder
{
 protected $zip;
 protected $root;
 protected $ignored_names;
   
 function __construct($file, $folder, $ignored=null)
 {
  $this->zip = new ZipArchive();
  $this->ignored_names = is_array($ignored) ? $ignored : $ignored ? array($ignored) : array();
  if($this->zip->open($file, ZIPARCHIVE::CREATE)!==TRUE) {throw new Exception("cannot open <$file>\n");}
  $folder = substr($folder, -1) == '/' ? substr($folder, 0, strlen($folder)-1) : $folder;
  if(strstr($folder, '/'))
  {
   $this->root = substr($folder, 0, strrpos($folder, '/')+1);
   $folder = substr($folder, strrpos($folder, '/')+1);
  }
  $this->zip($folder);
  $this->zip->close();
 }
   
 function zip($folder, $parent=null)
 {
  $full_path = $this->root.$parent.$folder;
  $zip_path = $parent.$folder;
  $this->zip->addEmptyDir($zip_path);
  $dir = new DirectoryIterator($full_path);
  foreach($dir as $file)
  {
   if(!$file->isDot())
   {
    $filename = $file->getFilename();
    if(!in_array($filename, $this->ignored_names))
    {
     if($file->isDir()) {$this->zip($filename, $zip_path.'/');}
     else {$this->zip->addFile($full_path.'/'.$filename, $zip_path.'/'.$filename);}
    }
   }
  }
 }
}

при малом количестве файлов и папок, подпапок - код работает.

В обоих случаях при большом количестве файлов и вложенных папок выскакивает ошибка: failed to open dir: Too many open files in ...

Как можно от этого избавиться?

Спасибо.

спустя 3 часа 4 минуты [обр] Алексей Полушин(62/231)[досье]
exec("zip -r $file $folder") подойдет ?
спустя 10 часов [обр] tcolonel[досье]

Нет, не подойдет, потому как при этом браузер виснет на больших объемах. А вот system или shell_exec - вполне.

Вопрос теперь в другом, как проверить что команда выполнилась успешно?

Если я делаю вывод в браузер, тогда браузер опять виснет, а если делаю в файл zip -r -y -v ... > $file, то в файле появляется adding:... - для каждого файла (и таких строк 1к, а то и больше). И только в конце файла появляется надпись total bytes=13490, compressed=9598 -> 29% savings. Вопрос в том, как проверить что архив создался нормально и команда отработала без ошибок? На ум приходит только парсинг файла > $file (в описании zip я не нашел подобного параметра, который возвращал бы код ошибки). Может есть идеи получше?

Спасибо.

спустя 39 минут [обр] Прокаев2(13/35)[досье]
проверить второй параметр после выполнения system ?
спустя 1 день [обр] tcolonel[досье]
Спасибо. Посмотрю что из этого выйдет.
спустя 2 месяца 27 дней [обр] tcolonel[досье]

Вопрос опять стал актуальным. Что лучше использовать для архивации маленьких файлов в большом количестве: tar, zip, gzip?

Спасибо.

спустя 19 часов [обр] Филипп Ткачев(20/112)[досье]
tar не архиватор.
Делайте как привычно. В *nix делают сначала tar, его потом сжимают gzip'ом.
спустя 1 час 8 минут [обр] tcolonel[досье]

Тут все дело в том, что много мелких файлов и даже через консоль (SSH) не всегда получается сделать архив (у меня не хватает опыта в *nix - чтобы разобраться в проблеме). Поэтому решил потестировать и узнать у знающих людей какое ПО лучше выбрать.

Спасибо за внимание.

Powered by POEM™ Engine Copyright © 2002-2005