2008-10-02 3 views
19

fopen не работает, когда я пытаюсь читать файл с очень умеренным размером в PHP. A 6 meg file заставляет его задыхаться, хотя мелкие файлы вокруг 100k в порядке. я читал, что иногда необходимо перекомпилировать PHP с флагом -D_FILE_OFFSET_BITS=64, чтобы читать файлы более 20 концертов или что-то нелепое, но разве у меня нет проблем с файлом размером 6 мегабайт? В конце концов, мы захотим прочитать файлы размером около 100 мегабайт, и было бы неплохо открыть их, а затем прочитать их по строкам с помощью fgets, поскольку я могу делать с меньшими файлами.Чтение очень больших файлов в PHP

Каковы ваши трюки/решения для чтения и выполнения операций с очень большими файлами в PHP?

Обновление: Вот пример простого кода, который не работает в моем 6-мегабайтном файле - PHP, похоже, не выдает ошибку, он просто возвращает false. Может, я делаю что-то очень глупое?

$rawfile = "mediumfile.csv"; 

if($file = fopen($rawfile, "r")){ 
    fclose($file); 
} else { 
    echo "fail!"; 
} 

Еще одно обновление: Спасибо всем за вашу помощь, она оказывается что-то невероятно тупой - проблема с разрешениями. У моего маленького файла необъяснимо были права на чтение, если в более крупном файле этого не было. Doh!

+0

Вы просто пытаетесь передать файл через? то есть. Скачать? Или вы на самом деле разбираете данные в файлах для какой-то цели? Спасибо. – DreamWerx 2008-10-02 13:21:38

+0

он не должен прерываться без создания предупреждения/ошибки. Пожалуйста, включите все ошибки с помощью error_reporting (E_ALL) и убедитесь, что display_errors настроены на отображение в браузере или проверьте журнал ошибок веб-серверов. – 2008-10-02 13:54:13

ответ

36

Вы уверены, что это fopen, который неисправного и не настройки тайм-аута вашего скрипта? По умолчанию обычно около 30 секунд или около того, и если ваш файл занимает больше времени, чем для чтения, это может привести к его отключению.

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

Если ни одна из вышеперечисленных проблем не является вашей проблемой, вы можете ознакомиться с использованием fgets, чтобы прочитать файл по очереди, обрабатывая по мере поступления.

$handle = fopen("/tmp/uploadfile.txt", "r") or die("Couldn't get handle"); 
if ($handle) { 
    while (!feof($handle)) { 
     $buffer = fgets($handle, 4096); 
     // Process buffer here.. 
    } 
    fclose($handle); 
} 

Редактировать

PHP, кажется, не выдаст ошибку, он просто возвращает ложь.

Является ли путь к $rawfile правильным относительно того, где работает скрипт? Возможно, попробуйте установить абсолютный путь здесь для имени файла.

0

Ну, вы можете попробовать использовать функцию readfile, если хотите просто вывести файл.

Если это не так - возможно, вам стоит подумать о дизайне приложения, почему вы хотите открыть такие большие файлы в веб-запросах?

+0

Мы должны автоматизировать добавление больших наборов данных, поэтому большие файлы CSV могут быть загружены пользователем и проанализированы и интегрированы в базу данных приложением. Мне бы понравились другие предложения для подхода, если вы считаете, что чтение и синтаксический анализ загруженных файлов с помощью PHP - это не лучший способ. – 2008-10-02 13:22:48

+0

Я бы не думал, что у PHP возникнет проблема с файлами csv 6MB? Кажется, это достаточно маленький файл для его обработки. В соответствии с комментариями выше, пожалуйста, сообщите точную ошибку/и/или код. Может быть ошибка памяти вашего удара? Или max_execution_time? Нам нужна дополнительная информация. – DreamWerx 2008-10-02 13:25:41

1

Я использовал fopen для открытия видеофайлов для потоковой передачи, используя php-скрипт в качестве сервера потоковой передачи видео, и у меня не было проблем с файлами размером более 50/60 МБ.

-1

Вы попробовали файл()?

http://is2.php.net/manual/en/function.file.php

Или file_ get_contents()

http://is2.php.net/manual/en/function.file-get-contents.php

+0

Будьте осторожны с файлом_get_contents() для больших файлов. Хотя 6 мегабайт должно быть хорошо, потоковая передача намного лучше, поскольку он сначала не считывает весь файл в память. – 2014-04-10 18:04:31

0

Если проблема вызвана ударом по памяти, вы можете попробовать установить более высокое значение (это может работать или не зависит от конфигурации php).

это устанавливает предел памяти до 12 Мб

ini\_set("memory_limit","12M"); 
0

для меня, FOPEN() очень медленно с файлами более 1 Мб, файл() гораздо быстрее. Просто пытаясь читать строки 100 за раз и создавать пакетные вставки, fopen() занимает 37 секунд, а файл() занимает 4 секунды. Должен быть, что string-> array step встроен в файл()

Я бы попробовал все параметры обработки файлов, чтобы увидеть, что лучше всего будет работать в вашем приложении.

5

ли 2 теста с файлом 1.3GB и 9.5GF Файл

1,3

Использование fopen()

Этот процесс используется 15555 мс для своих вычислений.

Он провел 169 мс в системе вызывает

Использование file()

Этот процесс используется 6983 мс для своих вычислений.

Он провел 4469 мс в системе вызывает

9.5GB

Использование fopen()

Этот процесс используется 113559 мс для своих вычислений

Это затраченных 2532 мс в системе вызывает

Использование file()

Этот процесс используется 8221 мс для своих вычислений

Он провел 7998 мс в системе называет

Кажется file() быстрее