Удалить первые X строк из файла PHP
Мне было интересно, если кто-нибудь там знал, как это можно сделать в PHP. Я запускаю скрипт, который включает в себя открытие файла, взятие первых 1000 строк, выполнение некоторых вещей с этими строками, затем php-файл открывает другой экземпляр самого себя, чтобы взять следующие тысячи строк и так далее, пока не достигнет конца файла, Я использую объект splfile, так что я могу искать определенную строку, что позволяет мне довольно хорошо разбить ее на 1000 строк. Самая большая проблема, с которой я столкнулся, связана с производительностью. Я имею дело с файлами, которые содержат более 10 000 000 строк, и хотя первые 10 000 строк или около того они выполняются довольно быстро, после этого момента наблюдается значительное экспоненциальное замедление, которое, я думаю, просто требует поиска этой точки.
Я хотел бы прочитать первые тысячи строк, а затем просто удалить их из файла, чтобы мой сценарий всегда читал первые тысячи строк. Есть ли способ сделать это без чтения остальной части файла в память. Другие решения, которые я видел, включают чтение каждой строки в массиве, а затем избавление от первых X записей, но с десятью миллионами строк, которые потребляют слишком много памяти и времени.
Если у кого-то есть решение или другие предложения, которые бы ускорили работу, это будет с благодарностью.
2 ответа
К сожалению, нет реального решения этой проблемы, потому что файлы всегда полностью загружаются в основную память, прежде чем они будут прочитаны.
Тем не менее, я опубликовал этот ответ, потому что это возможное решение, но я подозреваю, что оно вряд ли улучшает производительность. Поправь меня, если я ошибаюсь.
Вы можете использовать XML, чтобы разделить файлы на 1000 строк. И использовать DomDocument Class of PHP для извлечения и добавления данных. Вы можете добавить дочерний элемент, если хотите добавить данные и получить первый дочерний элемент, чтобы получить первую тысячу строк, и удалить его, если хотите. Именно так:
<document>
<part>
. . .
Thousand lines here
. . .
</part>
<part>
. . .
Thousand lines here
. . .
</part>
<part>
. . .
Thousand lines here
. . .
</part>
.
.
.
</document>
ПО-ДРУГОМУ:
Если вы действительно уверены в том, что разделите разделы на ровно 1000 строк, почему бы не сохранить их в базе данных, где каждая 1000 в другой строке? Делая это, вы наверняка сократите накладные расходы на чтение / запись файла и улучшите производительность.
Мне кажется, что цель состоит в том, чтобы проанализировать огромное количество данных и вставить их в базу данных? Если так, я не понимаю, почему так важно работать ровно с 1000 строками?
Я думаю, что просто подхожу к нему, читая большой объем данных, скажем, 1 МБ, в память сразу, а затем сканирую в обратном направлении от конца фрагмента в памяти для поиска конца последней строки. Получив это, я могу сохранить положение файла и дополнительные данные, которые у меня есть (что осталось от последней строки, заканчивающейся до конца фрагмента). В качестве альтернативы просто сбросьте указатель на файл с помощью fseek(), чтобы в том месте, где в файле я обнаружил окончание последней строки, легко выполнить с помощью strlen($chunk).
Таким образом, все, что мне нужно сделать, это разорвать порцию, запустив explode("\r\n", $chunk), и у меня есть все нужные мне строки в достаточно большом блоке для дальнейшей обработки.
Удаление строк из начала файла не рекомендуется. Это будет перетасовывать огромное количество данных назад и вперед на диск.