Чтение и деление на части большого текстового файла(40-80 мб)

Redwind

Новичок
Чтение и деление на части большого текстового файла(40-80 мб)

Есть большой текстовый(txt) файл (размером 40-80 мб). Его необходимо разделить на маленькие файлы размером 100 строк(меньше 1 кб). Сейчас я пользуюсь такой конструкцией(общая логика работы):
PHP:
$keys = fopen ($input_file, "r");
while(!feof($keys))
   {
   $write=fopen ($output_file."/".time().mt_rand(10, 99).mt_rand(10, 90).".txt", "w+");
   for($t=0; $t<100; $t++)
      {
      fwrite ($write, fgets($keys, 1024);
      }
   fclose ($write);
   }
fclose ($keys);
Как это сделать, чтобы как можно меньше грузить сервер?
 

Фанат

oncle terrible
Команда форума
Вообще-то, случайное имя генерить - это странная мысль.
почему нельзя ввести счетчик, и добавлять его?

А в остальном - для пхп алгоритм нормальный, и оптимизировать, как тут уже сказали, стоит в сторону внешних утилит
 

Redwind

Новичок
Появилась еще одна одна задача. В файле того-же размера нужно узнать количество строк в нем
PHP:
count(file("file.txt"));
естественно не катит, так как жрет много ресурсов
Пробовал так:
PHP:
$koef=0;//число строк
$fp = fopen ("file.txt", "r");
while(!feof($fp))
   {
   fgets($fp, 1);
   $koef++;
   }
fclose ($fp);
- занимает слишком много времени, что не приемлемо.
Подскажите плиз как можно еще поступить в данной ситуации.
 

Фанат

oncle terrible
Команда форума
оптимизировать, как тут уже сказали, стоит в сторону внешних утилит

man wc
 

stas_t

Новичок
судя по вопросам, вы из под винды работаете. split и wc вам тут не помощники. придётся делать самому

второй алгоритм, похоже, правильный, но только из файла надо читать не один байт, а одну строку (fgets ($fp) без второго параметра)

с первым алгоритмом у вас определённая проблема. проверка на конец файла у вас происходит один раз на 100 строк. я бы сделал по-другому:
PHP:
$keys = fopen ($input_file, "r");
for ($buffer='', $i=1, $j=1; !feof ($keys); $i++)
{
    $buffer .= fgets ($keys, 1024);
    if ($i==100)
    {
        file_put_contents ("$input_file.$j", $buffer);
        $buffer = '';
        $i = 1;
        $j++;
    }
}
fclose ($keys);
if (strlen ($buffer))
    file_put_contents ("$input_file.$j", $buffer);
 

Фанат

oncle terrible
Команда форума
stas_t
вы из под винды работаете. split и wc вам тут не помощники.
ты не в первый раз пишешь полную чушь.
старайся следить, всё-таки, за своими мыслями.
 

stas_t

Новичок
Фанат
мы с вами на брудершафт ещё не пили. следите за языком

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

Фанат

oncle terrible
Команда форума
stas_t
если тебя что-то не устраивает в моем стиле общения, то ты имеешь полное и неотъемлемое право со мной не общаться.
претензии к алгоритму есть?
есть. их сформулировал автор в своем вопросе.
и ему уже ответили.
если не можешь сказать по вопросу ничего нового, то лучше промолчать.
 

Anarki

Новичок
stas_t
Да пожалуйста, мне то что.
Есть претензии к реализованному алгоритму - его быстродействие и расход процессорного времени.

Решается как? делается например
PHP:
$output = system("быстрая_внешняя_программа_обработки_данных $input_file $param2");
и, скажете, это не соответсвует тематике форума?
 

stas_t

Новичок
для первого случая проблема с производительностью решается сокращением в 100 раз операций записи. строки сначала считываются в память, а потом записываются в файл блоком.

для второго случая проблема с производительностью кроется в неправильном использовании второго параметра fgets -- из файла читается 1 байт, а не строка.

надо послушать автора, насколько его устраивает решение. Redwind, сдвиги есть?
 

Фанат

oncle terrible
Команда форума
По поводу замечания про чтение одного байта замечание правильное.
учитывая тот факт, что такой скрипт вообще никогда не завершит работу.

В общем, Redwind, тебе замечание.
В следующий раз, если захочешь что-то сюда написать, то в обязательном порядке приводишь результаты своих действий В ЦИФРАХ. Сколько секунд конкретно занимает это " слишком много времени".
 

Li$

Новичок
Помоему автор в первом примере имел ввиду общий принцип работы, а не приведенный код в частности - он так и написал "(общая логика работы)".
По поводу 1 байта замечание правильное.
 

Redwind

Новичок
Помоему автор в первом примере имел ввиду общий принцип работы, а не приведенный код в частности - он так и написал "(общая логика работы)".
Li$ Верно - показанный код был набросан для отражения общих принципов(на самом деле код во много раз больше и не очень удобен для восприятия).
Фанат Вдруг замечание после такого количества постов - странно. Не виноват же я в вашей перепалке с stas_t.
По поводу кода: fgets считывает файл построчно
и если строка больше второго параметра, то возращается только ее часть соответсвующая длине указанной во вторм параметре.
PS отказался от подсчета строк в файле впрнципе, т.к. низкая скорость этого процесса(около минуты) и большие затраты системных ресурсов не приемлемы(в моём случае)
 

Фанат

oncle terrible
Команда форума
Не стоит так вести себя. И изображать непонятливость.
Если ты не понял суть замечания - надо переспросить.
Я могу повторить ещё раз.
Если ты желаешь впредь получать консультации на этом форуме, то тебе следует приводить реальные цифры вместо туманных определений "слишком много времени" и реально работающий код вместо примерных неработоспособных набросков.

Эти две рекомендации - единственное, что тебя должно беспокоить. А не чьи-то перепалки или колиество комментариев.
Надеюсь, я понятно объяснил.
 
Сверху