我有 C 和 C++ 背景,但也玩过一些网络东西。我们所有 C 语言的人(希望如此)都知道在读取之前在 FILE*
上调用 feof
是错误的。这是 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);
但这不是重点。我尝试测试如果我“以错误的方式”做事情是否会失败,但我无法让它导致不正确的行为。这并不完全科学,但我认为值得一试。
那么,在 PHP 中的 fread
之前调用 feof
是不正确的吗?
有几种方法可以让 PHP 以不同于 C 版本的方式完成此操作,但我认为它们有缺点。
他们可以将其默认为 !EOF。这是次优的,因为对于某些极端情况它可能不正确。
他们可以在
fopen
调用期间获取文件大小,但这不适用于所有类型的文件资源,会产生不一致的行为并且会更慢。
最佳答案
在您尝试读取文件之前,PHP 不知道它是否在文件末尾。试试这个简单的例子:
<?php
$fp = fopen("/dev/null","rb");
while (!feof($fp)) {
$data = fread($fp, 1);
echo "read " . strlen($data) . " bytes";
}
fclose($fp);
?>
您将得到一行读取 read 0 bytes
。 feof() 返回真,即使您在技术上位于文件末尾。通常这不会导致问题,因为 fread($fp, 1)
不返回任何数据,并且您正在执行的任何处理都不会处理任何数据。如果您确实需要知道自己是否在文件末尾,则必须先进行读取。
关于PHP 的 feof 行为与 C 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3239481/