прочитать большой файл в php (более 500мб)

Мне нужно прочитать большой файл, чтобы найти несколько меток и создать динамическую форму. Я не могу использовать file() или file_get_contents() из-за размера файла. Если я прочитаю файл построчно со следующим кодом

set_time_limit(0);    
$handle = fopen($file, 'r');
    set_time_limit(0);
    if ($handle) {
        while (!feof($handle)) {
            $line = fgets($handle);
            if ($line) {            
             //do something.
            }
        }
    }

    echo 'Read complete';

Я получаю следующую ошибку в Chrome:

Ошибка 101 (net::ERR_CONNECTION_RESET)

Эта ошибка возникает через несколько минут, так что константа max_input_time, я думаю, не является проблемой (установлена ​​на 60).


person alsanal    schedule 28.11.2012    source источник
comment
Сколько оперативной памяти у вас есть?   -  person Chris Bornhoft    schedule 28.11.2012
comment
Я посмотрел использование оперативной памяти в диспетчере задач. Это полностью. Зачем? если я читаю файл построчно...   -  person alsanal    schedule 28.11.2012


Ответы (3)


Какой браузер вы используете? Апач, нгинкс? Вы должны установить максимально допустимую загрузку файлов где-то выше 500 МБ. Кроме того, максимальный размер загрузки в php.ini также должен быть больше 500 МБ, и я думаю, что PHP должно быть разрешено создавать процессы размером более 500 МБ. (проверьте это в конфигурации php).

person Bastiaan Zwanenburg    schedule 28.11.2012
comment
Я использую apache... но я не понимаю. Я не хочу загружать файл (Файл уже на сервере), я просто хочу читать построчно, чтобы найти совпадения... - person alsanal; 28.11.2012
comment
О, извините, чем я неправильно вас понял. Какую операционную систему ты используешь? Каков размер ОЗУ вашего сервера и максимально допустимое использование ОЗУ одним процессом Apache? - person Bastiaan Zwanenburg; 28.11.2012
comment
Я использую окна 7 и xampp. 4gb Ram... Где я могу это увидеть? максимально допустимое использование ОЗУ одним процессом apache? - person alsanal; 28.11.2012

Установите лимит памяти ini_set("memory_limit","600M");также необходимо установить лимит тайм-аута

set_time_limit(0);
person Navneet Singh    schedule 28.11.2012

Как правило, длительные процессы не должны выполняться, пока пользователи ждут их завершения. Я бы рекомендовал использовать инструмент, ориентированный на фоновые задания, который может обрабатывать этот тип работы и может быть запрошен о статусе задания (выполняется/завершено/ошибка).

Мое первое предположение состоит в том, что что-то посередине разрывает соединение из-за тайм-аута. Будь то тайм-аут в веб-сервере (о котором PHP не может знать) или какой-то брандмауэр, это не имеет большого значения, PHP получает сигнал закрыть соединение, и скрипт перестает работать. Вы можете обойти это поведение, используя ignore-user-abort(true), это вместе с set_time_limit(0) должно помочь.

Предостережение заключается в том, что все, что вызвало прерывание соединения, все равно сделает это, хотя скрипт все равно завершит свою работу. Один очень раздражающий побочный эффект заключается в том, что этот сценарий может выполняться несколько раз параллельно, и ни один из них никогда не завершается.

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

person Or Cohen    schedule 28.11.2012
comment
Спасибо за ответ. проблема в том, что оперативная память заполняется, но я не понимаю, почему чтение файла построчно так сильно использует оперативную память. Использование фонового процесса вызовет ту же проблему? - person alsanal; 28.11.2012
comment
Я думаю, что это решение хорошее (я рекомендую использовать для этого какую-нибудь фоновую задачу и интерфейс для конечного пользователя (браузера) для проверки статуса этой задачи. Вы также можете реализовать базовую задачу самостоятельно с помощью заданий cron и базы данных/текста. файлы, которые содержат статус.) Но ¿Как я могу отменить процесс? если у пользователя есть форма со статусом процесса и кнопка для его отмены? - person alsanal; 28.11.2012
comment
Для этого потребуется интерфейс для связи фонового процесса и веб-сервера. Если вам нужно только сигнализировать об уничтожении процесса, вы можете сделать это через APC (или аналогичный). Он может совместно использовать объекты между процессами PHP, поэтому у вас может быть общий ключ, который задание периодически проверяет. Что касается проблемы с оперативной памятью, если вы не используете какую-либо старую версию PHP, то некоторые переменные, вероятно, не очищаются. Попробуйте удалить все возможные переменные и очистить все объекты (обратите внимание на любые методы dispose/clear/close). - person Or Cohen; 28.11.2012