Работа с большими файлами (больше 100мб)

Статус
В этой теме нельзя размещать новые ответы.

PocketDevil

Постоялец
Регистрация
26 Янв 2008
Сообщения
92
Реакции
161
Требуется открыть и заменить в файле все строки содержащие #name#, скриптом.
Меня интересует как работать с большими файлами в php.
Знаю, что оно происходит в несколько этапов и через fopen.
1) Подсчет общего кол-ва строк
2) Чтение в цикле по n строк
3) Замена в прочитанных строках
Обратно к п.2, и так до конца файла.
У кого остались примеры. Спасибо
 
ну во первых 100 мб не такой и большой размер, с ним вполне можно работать

во вторых - "на лету" проще сделать - читаем - меняем - пишем, правда работать немного дольше будет

код будет наипримитивнейшим

кстати файлы с локали читать нужно? или через сеть?
 
Локально
Но у меня что-то не читает просто через
fopen
fread
fclose

Процесс висит, но ничего не выводит.
Файл на 30 метров работает без проблем, а вот больше 100 уже не хочет.
 
может ограничения где нидь стоят?
проверь конфиги сервера, пхп.ини и тд
я там лимит на 500метров выставил - нормально трудится всё
 
Так читать нужно не сразу все 100 метров, а кусками по несколько кб. Смотри второй аргумент fread или возможно fgets лучше подойдёт (без второго аргумента читает ровно 1 строку до перевода).
 
fgets для чтения из файла вообще не подходит никак кроме разве что самых примитивных случаев, из-за проблем с выделением памяти под читаемую строку.


Пример:
PHP:
$fr=fopen('file.txt','r');


while(!feof($fr)) {

//////////////////// Замена fgets (если файл в формате windows):
$str='';
while("\r"!==($chr=fgetc($fr)) && (!feof($fr))){
	$str.=$chr;
}
fgetc($fr);
///////////////////////////////////////////////////////////////

...
<обработка строки $str>
$str=str_replace(#name#,$value,$str);
<вывод строки $str например в другой файл>
...

}
fclose($fr)

В этом случае файл может быть сколь угодно большим (десятки гигабайт) Дополнительно строки считать не надо, разумные ограничения сервера тоже похуй.
 
fgets для чтения из файла вообще не подходит никак кроме разве что самых примитивных случаев, из-за проблем с выделением памяти под читаемую строку.

И какие же проблемы? В сети ничего не нашёл, разумных предположений - ноль.

Множественная конкатенация может и экономна к памяти, но всё же достаточно трудоёмка при большой длине строки.
 
Генерал, как всегда помог, это то что я и искал.
Спасибо всем.
 
И какие же проблемы? В сети ничего не нашёл, разумных предположений - ноль.
Множественная конкатенация может и экономна к памяти, но всё же достаточно трудоёмка при большой длине строки.
1. Открываем php.net и читаем описание функции fgets, все проблемы описаны там в комментах.
2. Проверено лично мной - если в считываемом файле имеются строки большие чем допустим 500 кб, надо под них выделять память в fgets и эта память все равно выделяется независимо от длины считываемой строки, что приводит к большим тормозам в скрипте.
3. В моем варианте скорость обработки большого файла увеличивается в разы по сравнению с вариантом fgets.

Проверь сам :p


Кстати еще мной замечено - при обработке больших файлов/данных (гигабайты) многие библиотечные функции php начинают вести себя неадекватно и приходится их разворачивать. Пример - fgets, serialize.
 
3. В моем варианте скорость обработки большого файла увеличивается в разы по сравнению с вариантом fgets.
Проверь сам :p

ХМ, я заинтересовался и проверил

файл 10гб - просто читаем строки без всякой обработки , с обычным счетчиком строк

ну собственно вот:

1 вариант - твой (кстати у тя в коде ; не хватает )
Open 1 is ok
Страница сгенерирована за 168.189232 секунд!

2 вариант - эфгетс
Open 2 is ok
Страница сгенерирована за 2.767829 секунд!

сдается, что не всё так со скоростью, как описано выше
цифры сами за себя говорят :)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху