С нами с 10.12.03
Сообщения: 764
Рейтинг: 195
|
Добавлено: 01/11/04 в 11:27 |
сабж.
как лучше это организовать?
тоесть есть текстовый файл ну скажем 1М(это для примера, он и 10М может быть) и нужно считать оттуда строчку с номером N
и ещё из тойже темы - как лучше узнать число строк в этом файле
вообще какие варианты есть?
любые полезные советы/примеры оценятся по максимуму ;)
|
|
|
|
С нами с 07.01.04
Сообщения: 2868
Рейтинг: 1536
|
Добавлено: 01/11/04 в 11:42 |
Вот так будет самый быстрый вариант. Сколько всего строк тоже считается.
Код: |
<?
$f = fopen ("tempfile", "r");
$count = 0;
$mystr = 114; // номер нужной строки
while (!feof ($f)) {
$str = fgets ($f);
$count++;
if ($count == $mystr)
echo $str;
}
echo "Total strings: $count";
fclose ($f);
?>
|
|
|
|
|
С нами с 27.02.03
Сообщения: 873
Рейтинг: 402
|
Добавлено: 01/11/04 в 11:53 |
Копай на тему seek. В php соответствующая функция кажется fseek называется.
Чтобы строки посчитать - придется конечно весь файл считать. Немного убыстрить предыдущий вариант можно, не считывая каждую строку в переменную, а просто пробегаясь по ним и инкрементируя каунтер, а считывать только нужную строчку.
|
|
|
|
С нами с 29.09.00
Сообщения: 156
Рейтинг: 92
|
Добавлено: 01/11/04 в 11:54 |
хм, может там размеры конечно гиги, но так вроде бы проще, особенно если уже известен номер строки в файле:
Код: | <?
$n=125;//номер строки
$infile=file("файлстекстом");//читаем в массив файл, где каждый элемент это строка файла
echo count($infile); // печать сколько строк в файле
echo $infile[$n-1]; // печать нужной строки
?> |
код исправлен по указанию JpS :-)
Последний раз редактировалось: R.Bear (01/11/04 в 14:17), всего редактировалось 1 раз
|
|
|
|
С нами с 27.02.03
Сообщения: 873
Рейтинг: 402
|
Добавлено: 01/11/04 в 12:18 |
R.Bear писал: | хм, может там размеры конечно гиги, но так вроде бы проще, особенно если уже известен номер строки в файле |
Нет, не проще. Так куча говна сразу в память грузится...
|
|
|
|
С нами с 13.08.03
Сообщения: 533
Рейтинг: 481
|
Добавлено: 01/11/04 в 12:54 |
rADja писал: | тоесть есть текстовый файл ну скажем 1М(это для примера, он и 10М может быть) и нужно считать оттуда строчку с номером N
|
exec("head -n N file | tail -n 1");
rADja писал: |
и ещё из тойже темы - как лучше узнать число строк в этом файле
|
exec("wc -l file");
раскрасить по вкусу под местные условия
Последний раз редактировалось: dm (01/11/04 в 13:07), всего редактировалось 2 раз(а)
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 01/11/04 в 12:58 |
эхх... люблю извраты...
самый быстрый и самый короткий способ подсчитать строки:
Код: | $str_cnt=count(file("filename"));
|
памяти жрет больше, согласен...
P.S. 2R.Bear: count - это функция, а не переменная.
|
|
|
|
пенсионер
С нами с 07.11.02
Сообщения: 2612
Рейтинг: 1166
|
Добавлено: 01/11/04 в 13:08 |
dm самый грамотный способ сказал для больших обьемов...
а варианты с count(file("filename")) - для обьема больше пары мегабайт это вообще убийство памяти и проца.
хотя для файла в пару килобайт - этот способ наоборот очень даже неплох
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 01/11/04 в 13:21 |
да, согласен, у dm-a возможно быстрее будет, но уж то что меньше памяти будет жрать - точно.
просто когда я писал свой топик, dm писал свой и его ответа я не видел.
кстати мысль вызывать что-нибудь внешнее мне приходила в голову, но я думал это "чит" :)
тогда вот вам такой вариант? :)
dl("php_ext_count_line");
php_func_count_line("filename");
экстеншн написан Ц, значит быстрее встроенных функций.
dl приведен в качестве примера, вообще можно грузить заранее, через конфиг, чтобы всегда в памяти был, так что всеравно быстрее ;)
|
|
|
|
С нами с 10.12.03
Сообщения: 764
Рейтинг: 195
|
Добавлено: 01/11/04 в 14:04 |
в моём случае боюсь exec() не всегда подойдёт, т.к.
"Если PHP используется в безопасном режиме, system(), exec() и другие функции, выполняющие системные программы, не стартуют программы, которые находятся вне данной директории. "
да и в некоторых местах exec() просто не работает...
но буду иметь ввиду...
мне вообще желательно не использовать "что-нибудь внешнее"
в любом случае всем спасибо
если вдруг есть ещё варианты, кидайте
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 01/11/04 в 14:08 |
ну если тебе не нужен тюнинг и лишние траблы, то имху, первый вариант предложенный kink-ом, самый лучший.
все остальное - это "игры разума" :)
|
|
|
|
С нами с 13.08.03
Сообщения: 533
Рейтинг: 481
|
Добавлено: 01/11/04 в 16:56 |
да, если голый PHP - тут только fgets() и вперед на амбразуру считать.. буфер разве что побольше сразу
|
|
|
|
С нами с 30.06.03
Сообщения: 794
Рейтинг: 202
|
Добавлено: 02/11/04 в 18:59 |
Конструкция вида
$f=fopen("file","r");
while(!feof($f)){
$s=fgets($f);
}
fclose($f);
самый медленный вариант. Самый быстрый через fread.
В умной книжке написано
|
|
Я бы взял частями, но мне нужно сразу=))
|
0
|
|
|
пенсионер
С нами с 07.11.02
Сообщения: 2612
Рейтинг: 1166
|
Добавлено: 02/11/04 в 19:31 |
Alpha_Juno писал: | Конструкция вида
...
$s=fgets($f);
...
самый медленный вариант. Самый быстрый через fread.
В умной книжке написано |
Гы
а в этой умной книжке, о том как через fread узнать на какой строке стоит поинтер или как через него считать конкретную строку, - ничего не написано ? ;)
тыб хоть читал о чем речь.
|
|
|
|
С нами с 30.06.03
Сообщения: 794
Рейтинг: 202
|
Добавлено: 02/11/04 в 20:10 |
Остается оди вариант если нужна конкретная строка и важна скорость: file()
Из той же умной книжки
|
|
Я бы взял частями, но мне нужно сразу=))
|
0
|
|
|
пенсионер
С нами с 07.11.02
Сообщения: 2612
Рейтинг: 1166
|
Добавлено: 02/11/04 в 22:30 |
Alpha_Juno, нахрена давать советы если ты в теме не разбираешся ???
создай на компе текстовый файл размером 200мб, возьми секундамер (или скорее всего будильник) и попробуй своим способом найти 10.000ю строчку если получится.
потом перечитай внимательно топик и попробуй предложенные выше способы. после чего ,если поймешь что к чему, можешь выкинуть умную книжку и начать изучать програмирование на практике, а не в теории.
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 02/11/04 в 22:40 |
ругаться вот только не нужно.
замечание актуальное, но не совсем верное.
при _достаточном_ количестве памяти file() будет работать быстрее чем fopen+fgets
|
|
|
|
пенсионер
С нами с 07.11.02
Сообщения: 2612
Рейтинг: 1166
|
Добавлено: 02/11/04 в 23:12 |
да никто и не ругается
JpS...
упростим задачу чтоб было еще наглядней....
файл 2мб...
считать нужно 3-ю строчку от начала файла...
давайте проверим какой вариант из предложенных будет работать быстрее ;)
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 02/11/04 в 23:17 |
bog писал: | да никто и не ругается :)
JpS...
упростим задачу чтоб было еще наглядней....
файл 2мб...
считать нужно 3-ю строчку от начала файла...
давайте проверим какой вариант из предложенных будет работать быстрее ;) |
ушел писать тест :)
|
|
|
|
С нами с 30.06.03
Сообщения: 794
Рейтинг: 202
|
Добавлено: 02/11/04 в 23:49 |
bog писал: | Alpha_Juno, нахрена давать советы если ты в теме не разбираешся ??? |
Я все правильно расписал, file быстрее, fgets медленние.
bog писал: | создай на компе текстовый файл размером 200мб, возьми секундамер (или скорее всего будильник) и попробуй своим способом найти 10.000ю строчку если получится. |
Только не на моем компе. Это получится не тест скорости скрипта а тест на живучесть файловой системы
bog писал: | можешь выкинуть умную книжку и начать изучать програмирование на практике, а не в теории. |
Я этим и занимаюсь А книжка пусть будет, я все время забываю что там в str_pos указывать
При размере в 2мб разницы нет никакой, сам только что проверял.
|
|
Я бы взял частями, но мне нужно сразу=))
|
0
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 02/11/04 в 23:58 |
ну вобщем потестил.
2М - не прикольно. очень быстро.
взял 100Мб
читаю последнюю строчку из файла
тест с file: ~1,2 сек
тест с fopen/fgets: ~1,9 сек
|
|
|
|
С нами с 27.02.03
Сообщения: 873
Рейтинг: 402
|
Добавлено: 03/11/04 в 00:14 |
JpS писал: | читаю последнюю строчку из файла |
Ну е-мое тебе bog какую строчку сказал читать?
Прочитай 3-ью - и охуей насколько оно быстрее будет.
Прочитай в середине - сравни - охуей еще раз.
А потом посмотри сколько твой способ ресурсов жрет. Несколько таких процессов сервак загрузят.
В том бля и смысл практического программинга - нужно находить оптимальное сочетание скорости и потребления ресурсов, а не скорости и красоты кода, как в чистой теории.
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 03/11/04 в 00:24 |
сказать он мне мог все что угодно. он еще мог мне сказать не читать файл вообще например. эксперимент - на то и эксперимент, чтобы приблизить к боевым условиям. или задача стояла как "прочитать третью строчку"? разговор вообще шел о подсчете строк.
про ресурсы - это отдельный разговор. я специально для невнимательных _отметил_.
и как я писал выше - fopen/fgets - действительно оптимальное решение для этой задачи.
тест писался только для того чтобы опровергенуть неверное утверждение _только_ насчет времени.
кстати на маленьких файлах (до 10Мб) метод с file вполне может побороться как и по скорости, так и по ресурсам с методом fopen/fgets
|
|
|
|
/dev/awm
С нами с 05.02.04
Сообщения: 2300
Рейтинг: 1127
|
Добавлено: 03/11/04 в 00:27 |
кстати на середине файла они дали одинаковый результат...
|
|
|
|
пенсионер
С нами с 07.11.02
Сообщения: 2612
Рейтинг: 1166
|
Добавлено: 03/11/04 в 00:43 |
JpS писал: | эксперимент - на то и эксперимент, чтобы приблизить к боевым условиям. или задача стояла как "прочитать третью строчку"? разговор вообще шел о подсчете строк.
|
.
если боевые условия - то даешь среднюю нагрузку на сервак...
10 реквестов в секунду на этот скрипт ))
|
|
|
|