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

  • Автор темы Автор темы Redwind
  • Дата начала Дата начала

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);
Как это сделать, чтобы как можно меньше грузить сервер?
 
Вообще-то, случайное имя генерить - это странная мысль.
почему нельзя ввести счетчик, и добавлять его?

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

man wc
 
судя по вопросам, вы из под винды работаете. 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);
 
Фанат
мы с вами на брудершафт ещё не пили. следите за языком

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

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

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

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

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

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