提问人:Evan Teran 提问时间:7/14/2010 最后编辑:CommunityEvan Teran 更新时间:7/14/2010 访问量:565
PHP 的 feof 行为与 C 的行为
PHP's feof behavior versus C's
问:
我有 C 和 C++ 背景,但也玩一些网络东西。我们所有 C 人员(希望)都知道在进行读取之前调用 a 是错误的。这是经常刺痛 C 和 C++ 新手的东西。PHP的实现也是这样吗?feof
FILE*
我认为这一定是因为文件可能是一个套接字或其他任何在完成读取之前无法知道大小的东西。但是几乎每个PHP示例(甚至是我见过的 php.net 上找到的PHP示例看起来都是这样的(并且警报在我的脑海中响起):
$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);
?>
您将获得一行阅读。feof() 返回 true,即使您在技术上位于文件末尾。通常这不会导致问题,因为不返回任何数据,并且您正在执行的任何处理都不会处理任何数据。如果你真的需要知道你是否在文件的末尾,你必须先进行读取。read 0 bytes
fread($fp, 1)
您关于不在 an 之前打电话的断言是不正确的 - 因此这个问题是无效的。feof
fread
评论
feof
fopen
这可能更像是一个问题而不是答案,但为什么不使用 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:[email protected]/file.txt", $real_content, 0, $stream);
}
然后你不需要担心EOF或任何东西,它会为你做(ftp put有点危险,但没关系)。当然,这并非在所有情况下都有效......
我在原来的问题中是否遗漏了一些东西,使这种方法不可行?
评论
foef
评论