|
|
|
|
|
для: baston
(16.03.2010 в 13:23)
| | Сравните.
Сделайте выводы. | |
|
|
|
|
|
|
|
для: Trianon
(16.03.2010 в 13:04)
| | Благодарю!
Таким образом, можно ли считать, что решение данной задачи с помощью этой функции является оптимальным решением и может использоваться в реальной ситуации? | |
|
|
|
|
|
|
|
для: baston
(16.03.2010 в 12:46)
| | надо просто вызов записать полной формой
readwrite($fd, $part, $sizetomб $tom, $read); | |
|
|
|
|
|
|
|
для: 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");
|
| |
|
|
|
|
|
|
|
для: baston
(07.03.2010 в 19:33)
| | подход верный, но обилие констант прямо в записи цикла показывает, что вот эти строки использоваться не будут.
//Задаем размер считываемых данных за раз (не более 10 кб)
$read = 10240;
//Задаем максимальный размер тома (100 кб)
$tom = 102400;
|
а стоит сделать, чтобы применялись в конечном итоге именно значения этих переменных.
Еще полезно знать, что округление от деления a на b вверх быстро считается так:
$ n = (int)(($a+$b-1)/$b); | |
|
|
|
|
|
|
|
для: Trianon
(05.03.2010 в 10:42)
| | Простите, что опять напоминаю о себе :)
Можете вы оценить финальное решение данной задачи (код выше в предпоследнем сообщении)?
А то варюсь в собственном соку...
Буду очень благодарен за критику и указание на ошибки.
С уважением. | |
|
|
|
|
|
|
|
для: 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);
|
| |
|
|
|
|
|
|
|
для: Trianon
(05.03.2010 в 10:42)
| | Честно говоря, бьюсь уже второй день над этой задачей и не продвинулся ни на йоту.
Если я правильно понял вашу мысль, вы предлагаете читать из большого файла по маленькому кусочку (скажем, 10 кб) и записывать этот кусочек в том, пока размер тома не станет равным, например, 100 кб.
Я перепробовал разные варианты цикла, но все стопорится зацикливанием и созданием одного большого файла.
Уже отчаяние берет и мозги кипят, как говорится...
Может быть, еще какие наводки дадите? Например, какими функциями ограничиться, какими циклами...
Мне сложно выйти за рамки, так как практики-то маловато.
Можно было бы воспользоваться функцией file_get_contents(), но она сродни функции file и в память получается тоже заносится много данных... Или я не прав? | |
|
|
|
|
|
|
|
для: baston
(05.03.2010 в 07:58)
| | просто Вы кладете данные в том за один раз.
Представьте себе карьер с песком (это Ваш большой файл), кучу самосвалов, которыми этот песок нужно вывезти (это Ваши тома) и экскаватор (это Ваш скрипт).
У автора скрипта из книги экскаватор имел ковш размером с весь карьер.
Один раз зачерпнув всё, он отсыпал каждому самосвалу в кузов.
У Вас экскаватор имеет ковш размером с кузов самосвала.
Зачерпывает из карьера, насыпает в самосвал, зачерпывает - насыпает в следующий, и т.д.
Обычно же экскаватор насыпает самосвалы в несколько шагов.
Это позволяет ему иметь относительнокомпактный (по сравнению с размерами самосвала) ковш.
Размер ковша в этой аналогии - в чистом виде объем оперативной памяти, потребляемой скриптом. | |
|
|
|
|
|
|
|
для: Trianon
(04.03.2010 в 22:06)
| | Я думал над тем, что по окончании работы скрипта в памяти остается все, что мы занесли туда.
Может быть, стоит очищать память после каждой итерации?
Жаль, мало знаний для соображения о том, какую иную логику здесь можно применить....
За критику отдельное большое спасибо. | |
|
|
|
|