Удалить первые 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), и у меня есть все нужные мне строки в достаточно большом блоке для дальнейшей обработки.

Удаление строк из начала файла не рекомендуется. Это будет перетасовывать огромное количество данных назад и вперед на диск.

Другие вопросы по тегам