代码之家  ›  专栏  ›  技术社区  ›  Evan Teran

PHP的FEOF行为与C的比较

  •  6
  • Evan Teran  · 技术社区  · 14 年前

    我来自C和C++背景,但也玩一些网络的东西。我们所有的人(希望)都知道这个电话 feof 在一 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);
    

    但这也不重要。我试着测试如果我做了“错误的方式”,事情是否会失败,但我不能让它导致不正确的行为。这不太科学,但我觉得值得一试。

    所以,打电话不正确吗 飞行时间 之前 fread 在PHP中?

    有几种方法可以让PHP与C的版本有所不同,但我觉得它们有缺点。

    • 他们可以默认为!EOF。这是次最优的,因为它可能不适合某些角情况。

    • 他们可以在 fopen 调用,但这不能在所有类型的文件资源上工作,从而产生不一致的行为,并且速度会变慢。

    3 回复  |  直到 14 年前
        1
  •  3
  •   MightyE    14 年前

    在您尝试读取文件之前,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) 不返回任何数据,并且无论您正在进行什么处理,都不会处理任何数据。如果你真的需要知道你是否在文件的末尾,你必须先读一读。

        2
  •  0
  •   TCCV    14 年前

    这可能更像是一个问题而不是一个答案,但为什么不使用 file_get_contents() ?根据我的经验,如果您正在读取一个文件或流,这个函数会为您做一些不正常的工作(假设您希望将整个资源读取到一个字符串,或者知道/可以计算一个限制和偏移量)。它的姊妹函数文件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有点不确定,但没关系)。当然,这不会在所有情况下都起作用…

    最初的问题中是否有一些让这种方法不可行的地方我遗漏了?

        3
  •  -1
  •   Anonymous    14 年前

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