6

我来自 C 和 C++ 背景,但也玩过一些网络东西。我们所有的 C 人(希望如此)都知道feof在读取之前调用 aFILE*是一个错误。这是经常刺痛 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中调用feofan 之前是不正确的吗?fread

PHP 可以通过多种方式完成与 C 版本不同的操作,但我觉得它们也有缺点。

  • 他们可以将其默认为!EOF。这是次优的,因为它对于某些极端情况可能是不正确的。

  • 他们可以在调用期间获取文件大小fopen,但这不适用于所有类型的文件资源,从而产生不一致的行为并且速度会变慢。

4

3 回答 3

3

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() 也会返回 true。通常这不会导致问题,因为fread($fp, 1)不返回任何数据,并且您正在执行的任何处理都不会处理任何数据。如果你真的需要知道你是否在文件的末尾,你必须先阅读。

于 2010-07-13T17:17:44.763 回答
0

这可能更像是一个问题而不是答案,但为什么不使用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 有点冒险,但没关系)。当然,这并不适用于所有情况......

原始问题中是否有一些我遗漏的东西使这种方法不可行?

于 2010-07-13T17:43:48.080 回答
-1

feof你关于在 an 之前不打电话的断言fread是不正确的 - 因此这个问题是无效的。

于 2010-07-13T17:26:06.797 回答