Я работаю над странной проблемой PHP в последние несколько дней, когда функция feof() возвращает true до конца файла. Ниже приведен скелет моего кода:PHP feof() возвращает true до конца файла
$this->fh = fopen("bigfile.txt", "r");
while(!feof($this->fh))
{
$dataString = fgets($this->fh);
if($dataString === false && !feof($this->fh))
{
echo "Error reading file besides EOF";
}
elseif($dataString === false && feof($this->fh))
{
echo "We are at the end of the file.\n";
//check status of the stream
$meta = stream_get_meta_data($this->fh);
var_dump($meta);
}
else
{
//else all is good, process line read in
}
}
Через много испытаний я обнаружил, что программа отлично на все работы, кроме одного файла:
- Файл хранится на локальном диске.
- Этот файл содержит около 8 миллионов строк, усредняющих где-то около 200-500 символов в строке.
- Он уже был очищен и под тщательным изучением с шестнадцатеричным редактором, никаких аномальных символов не обнаружено.
- Программа последовательно терпит неудачу в строке 7172714, когда она считает, что она достигла конца файла (хотя у него есть ~ 800K строк слева).
- Я протестировал программу на файлы, в которых было меньше символов в строке, но было между 20-30 миллионами строк без проблем.
- Я попытался запустить код из комментария на http://php.net/manual/en/function.fgets.php, чтобы узнать, не было ли в этом коде что-то, что вызывало проблему, а сторонний код провалился в той же строке. EDIT: также стоит упомянуть, что сторонний код использовал fread() вместо fgets().
- Я попытался указать несколько размеров буфера в функции fgets, и ни одна из них не имела никакого значения.
Выход из var_dump ($ мета) выглядит следующим образом:
array(9) {
["wrapper_type"]=>
string(9) "plainfile"
["stream_type"]=>
string(5) "STDIO"
["mode"]=>
string(1) "r"
["unread_bytes"]=>
int(0)
["seekable"]=>
bool(true)
["uri"]=>
string(65) "full path of file being read"
["timed_out"]=>
bool(false)
["blocked"]=>
bool(true)
["eof"]=>
bool(true)
}
В попытке выяснить, что является причиной feof вернуть истинный до конца файла, я должен предположить, что либо :
A) что-то, что вызывает поток FOPEN на провал, и тогда ничто не может быть прочитан (вызывая feof вернуть истинный)
B) Существует некоторый буфер где-то, что заполнение и вызывает хаос
C) Боги PHP злится
Я искал повсюду, чтобы увидеть, если кто-то еще с этой проблемой и не могу найти какие-либо случаи, за исключением C++, где файл читается в виде текстового режима вместо и вызывал проблему.
UPDATE: У меня был мой скрипт, который постоянно выводил количество повторных попыток чтения и уникальный идентификатор пользователя, связанный с записью, найденной рядом с ним. Сценарий по-прежнему не работает после строки 7172713 из 7175502, но уникальный идентификатор последнего пользователя в файле отображается в строке 7172713. Кажется, что проблема по какой-то причине пропускается и не читается. Все разрывы строк присутствуют.
Возможно ли, что в php закончилось чтение файла? –
Вспомним, что функция чтения вызывается для блоков строк. Он считывает 500 строк, выполняет некоторую обработку и возвращает значение и сохраняет последнее местоположение в переменной класса. В следующий раз, когда он называется, он читает следующие 500 строк, начиная с которых он остановился, используя переменную класса. Все правильно рассмотрено с использованием unset и при мониторинге использования памяти сервера я не заметил ничего ненормального. Поскольку это было слишком сложно для проведения тестирования, я написал этот код и просто отключил строку, прочитанную в успешной строке. Все еще видя ту же проблему. – user2395126
вы пытались использовать 'rb' = ** читать двоичный код ** вместо просто' r'? –