feof поведение PHP по сравнению с C

Я происхожу из C и фона C++, но также и играю с некоторым веб-материалом. Все нас люди C (надо надеяться), знают тот вызов feof на a FILE* прежде, чем сделать чтение - ошибка. Это - что-то, что жалит новичков к C и C++ очень часто. Этот также имеет место для реализации PHP?

Я полагаю, что это должно быть, потому что файл мог быть сокетом или чем-либо еще, где невозможно знать размер прежде, чем закончить читать. Но примерно каждый пример PHP (даже найденные на php.net, который я видел, выглядят примерно так (и предупреждения уходят в моей голове):

$f = fopen("whatever.txt", "rb");
while(!feof($f)) {
    echo fgets($f);
}
fclose($f);

Я знаю, желательно писать это как это и избегать этой проблемы:

$f = fopen("whatever.txt", "rb");
while($line = fgets($f)) {
    echo $line;
}
fclose($f);

но это помимо точки. Я пытался тестировать, если вещи перестали бы работать, если бы я сделал это "неправильный путь", но я не мог бы заставить это вызывать неправильное поведение. Это не является точно научным, но я полагал, что это стоило попытки.

Так, это неправильный звонить feof перед fread в PHP?

Существует несколько способов, которыми PHP, возможно, сделал это по-другому, что версия C, но я чувствую, что у них есть оборотные стороны.

  • у них мог быть он значение по умолчанию к! EOF. Это является субоптимальным, потому что это может быть неправильно для некоторых угловых случаев.

  • они могли получить размер файла во время fopen звоните, но это не могло работать над всеми типами ресурсов файла, приводя к непоследовательному поведению и будет медленнее.

6
задан Evan Teran 13 July 2010 в 17:42
поделиться

3 ответа

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

<?php 
$fp = fopen("/dev/null","rb"); 
while (!feof($fp)) { 
    $data = fread($fp, 1);
    echo "read " . strlen($data) . " bytes";  
} 
fclose($fp); 
?>

Вы получите чтение одной строки , чтение 0 байтов . feof () вернул истину, даже если технически вы были в конце файла. Обычно это не вызывает проблем, потому что fread ($ fp, 1) не возвращает данных, и любая обработка, которую вы выполняете, не обрабатывает никаких данных. Если вам действительно нужно знать, находитесь ли вы в конце файла, вам нужно сначала выполнить чтение.

3
ответ дан 17 December 2019 в 20:28
поделиться

Это может быть больше похоже на вопрос, чем ответ, но почему бы не использовать file_get_contents () ? По моему опыту, если вы читаете файл или поток, эта функция выполняет грязную работу за вас (при условии, что вы хотите прочитать весь ресурс в строке или знаете / можете вычислить предел и смещение). Его сестринская функция file_put_contents () работает хорошо, наоборот.

Например, вот пример:

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("/path/to/file.txt");
if ($expected_content != $real_content){
   file_put_contents("/path/to/file.txt", $real_content);
}

или поток:

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("http://host.domain.com/file.txt");
if ($expected_content != $real_content){
   $options = array('ftp' => array('overwrite' => true));
   $stream = stream_context_create($options); 
   file_put_contents("ftp://user:pass@host.domain.com/file.txt", $real_content, 0, $stream);
}

Тогда вам не нужно беспокоиться об EOF или чем-то еще, он сделает это за вас (ftp put становится немного рискованным, но это нормально) . Конечно, это не сработает во всех ситуациях ...

Есть ли что-то, чего мне не хватает в исходном вопросе, что делает этот подход невозможным?

0
ответ дан 17 December 2019 в 20:28
поделиться

Ваше утверждение о том, что не вызывается feof перед fread , неверно - следовательно, вопрос неверен.

-1
ответ дан 17 December 2019 в 20:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: