Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Разбивка файла на части: как избавиться от файлов с нулевым размером?

Сообщения:  [1-10]    [11-20]  [21-21] 

 
 автор: Trianon   (16.03.2010 в 14:06)   письмо автору
 
   для: baston   (16.03.2010 в 13:23)
 

Сравните.
Сделайте выводы.

  Ответить  
 
 автор: baston   (16.03.2010 в 13:23)   письмо автору
 
   для: Trianon   (16.03.2010 в 13:04)
 

Благодарю!
Таким образом, можно ли считать, что решение данной задачи с помощью этой функции является оптимальным решением и может использоваться в реальной ситуации?

  Ответить  
 
 автор: Trianon   (16.03.2010 в 13:04)   письмо автору
 
   для: baston   (16.03.2010 в 12:46)
 

надо просто вызов записать полной формой
readwrite($fd, $part, $sizetomб $tom, $read);

  Ответить  
 
 автор: baston   (16.03.2010 в 12:46)   письмо автору
 
   для: Trianon   (08.03.2010 в 17:53)
 

Спасибо за подсказки.
Я, наконец, собрался с духом и вернулся к этому скрипту. Решил сделать всё простой функцией + использование вложенной функции. Не уверен, что это оптимально...
Однако столкнулся с тем, что у меня повторяются данные из первой функции во второй. Как это обойти - не соображу. Если можете, подскажите пожалуйста. Спасибо. Код ниже:
//Функция разбивки файла на части
function splitfile($fn)
{
  //Проверяем существование файла
  if(!is_file($fn)) {die("Файл не найден. Проверьте его существование.");}
  //Определяем размер файла
  $fs = filesize($fn);
  //Задаем размер считываемых данных за раз (не более 10 кб)
  $read = 10240;
  //Задаем максимальный размер тома (100 кб)
  $tom = 102400;
  //Определяем количество томов и увеличиваем, если есть хвостик
  $count = (int)(($fs+$tom-1)/$tom);
  //Определяем размер каждого тома и увеличиваем, если есть хвостик
  $sizetom = (int)(($fs+$count-1)/$count);
  //Открываем файл для чтения
  $fd = @fopen($fn, "rb");

  //Вложенная функция чтения данных по 10 кб и записи их в конец файла
  function readwrite($bigfile, $tomus, $maxsize, $tom = 102400, $read = 10240)
  {
    for($i=0; $i<$tom; $i+=$read)
    {
        $buf = fread($bigfile, $read);
        fwrite($tomus, $buf);
        ob_clean();
    }
  }
  //Проходим циклом и создаем части
  for($i=0; $i<$count; $i++)
  {
    $part = fopen("part.tm".$i, "ab");
    readwrite($fd, $part, $sizetom);
    fclose($part);
  }
  //Закрываем основной файл
  fclose($fd);
}
splitfile("clip2net082b.zip");

  Ответить  
 
 автор: Trianon   (08.03.2010 в 17:53)   письмо автору
 
   для: baston   (07.03.2010 в 19:33)
 

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

//Задаем размер считываемых данных за раз (не более 10 кб)
$read = 10240;
//Задаем максимальный размер тома (100 кб)
$tom = 102400;

а стоит сделать, чтобы применялись в конечном итоге именно значения этих переменных.
Еще полезно знать, что округление от деления a на b вверх быстро считается так:
$ n = (int)(($a+$b-1)/$b);

  Ответить  
 
 автор: baston   (08.03.2010 в 17:30)   письмо автору
 
   для: Trianon   (05.03.2010 в 10:42)
 

Простите, что опять напоминаю о себе :)

Можете вы оценить финальное решение данной задачи (код выше в предпоследнем сообщении)?
А то варюсь в собственном соку...
Буду очень благодарен за критику и указание на ошибки.
С уважением.

  Ответить  
 
 автор: baston   (07.03.2010 в 19:33)   письмо автору
 
   для: baston   (07.03.2010 в 15:35)
 

Вот так сейчас неожиданно получилось (добавил функцию). Поправьте, если опять есть неоптимальности или ошибки. Спасибо.
//Сохраняем в переменную название файла
$fn = "clip2net082b.zip";
//Проверяем существование файла в текущем каталоге (местонахождение скрипта)
if (!is_file($fn)) { die("Файл \"$fn\" не существует"); }
//Получаем размер файла в байтах
$size = filesize($fn);
//Задаем размер считываемых данных за раз (не более 10 кб)
$read = 10240;
//Задаем максимальный размер тома (100 кб)
$tom = 102400;
//Определяем количество томов
$count = (int)$size/$tom;    //~14 томов с хвостиком
//Увеличиваем количество томов, если есть хвостик
if((float)($size/$tom) - $count != 0) $count++;
//Определяем размер каждого тома
$sizetom = (int)$size/$count;
if((float)($size/$count) - $sizetom != 0) $sizetom++;
//Открываем файл в режиме чтения
$fd = fopen($fn, "rb");
//Функция чтения данных по 10 кб и записи их в конец файла
function readwrite($bigfile, $tomus, $maxsize)
{
  for($i=0; $i<102400; $i+=10240)
    {
        $buf = fread($bigfile, 10240);
        fwrite($tomus, $buf);
        ob_clean();
    }
}
for($i=0; $i<$count; $i++)
{
    $part = fopen("part.tm".$i, "ab");
  readwrite($fd, $part, $sizetom);
    fclose($part);
}
//Закрываем основной файл
fclose($fd);

  Ответить  
 
 автор: baston   (07.03.2010 в 15:35)   письмо автору
 
   для: Trianon   (05.03.2010 в 10:42)
 

Честно говоря, бьюсь уже второй день над этой задачей и не продвинулся ни на йоту.
Если я правильно понял вашу мысль, вы предлагаете читать из большого файла по маленькому кусочку (скажем, 10 кб) и записывать этот кусочек в том, пока размер тома не станет равным, например, 100 кб.
Я перепробовал разные варианты цикла, но все стопорится зацикливанием и созданием одного большого файла.
Уже отчаяние берет и мозги кипят, как говорится...
Может быть, еще какие наводки дадите? Например, какими функциями ограничиться, какими циклами...
Мне сложно выйти за рамки, так как практики-то маловато.
Можно было бы воспользоваться функцией file_get_contents(), но она сродни функции file и в память получается тоже заносится много данных... Или я не прав?

  Ответить  
 
 автор: Trianon   (05.03.2010 в 10:42)   письмо автору
 
   для: baston   (05.03.2010 в 07:58)
 

просто Вы кладете данные в том за один раз.

Представьте себе карьер с песком (это Ваш большой файл), кучу самосвалов, которыми этот песок нужно вывезти (это Ваши тома) и экскаватор (это Ваш скрипт).

У автора скрипта из книги экскаватор имел ковш размером с весь карьер.
Один раз зачерпнув всё, он отсыпал каждому самосвалу в кузов.
У Вас экскаватор имеет ковш размером с кузов самосвала.
Зачерпывает из карьера, насыпает в самосвал, зачерпывает - насыпает в следующий, и т.д.
Обычно же экскаватор насыпает самосвалы в несколько шагов.
Это позволяет ему иметь относительнокомпактный (по сравнению с размерами самосвала) ковш.

Размер ковша в этой аналогии - в чистом виде объем оперативной памяти, потребляемой скриптом.

  Ответить  
 
 автор: baston   (05.03.2010 в 07:58)   письмо автору
 
   для: Trianon   (04.03.2010 в 22:06)
 

Я думал над тем, что по окончании работы скрипта в памяти остается все, что мы занесли туда.
Может быть, стоит очищать память после каждой итерации?
Жаль, мало знаний для соображения о том, какую иную логику здесь можно применить....
За критику отдельное большое спасибо.

  Ответить  

Сообщения:  [1-10]    [11-20]  [21-21] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования