首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP的行为与C的对比

问PHP的行为与C的对比
EN

Stack Overflow用户
提问于 2010-07-13 16:57:30
回答 3查看 541关注 0票数 6

我来自C和C++背景,但也玩一些网络的东西。我们C级人员(希望如此)都知道,在读取之前在feof上调用FILE*是一个错误。对于C和C++来说,这是一件让新手很不爽的事情。PHP的实现也是这样吗?

我想,这必须是因为文件可能是一个套接字或其他任何东西,在完成阅读之前不可能知道大小。但是几乎每个PHP示例(甚至是我在php.net上看到的例子)看起来都是这样的(警报在我的脑海中响起):

代码语言:javascript
复制
$f = fopen("whatever.txt", "rb");
while(!feof($f)) {
    echo fgets($f);
}
fclose($f);

我知道,最好这样写,并避免这个问题:

代码语言:javascript
复制
$f = fopen("whatever.txt", "rb");
while($line = fgets($f)) {
    echo $line;
}
fclose($f);

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

那么,在PHP中调用feof fread 之前调用是否不正确?

与C版本相比,PHP有几种不同的方法可以做到这一点,但我觉得它们有缺点。

  • 他们可以让它默认为!EOF。这是次优,因为它可能是不正确的一些角落的情况。
  • 他们可以在fopen调用期间获得文件大小,但这不能在所有类型的文件资源上工作,从而产生不一致的行为,而且速度会更慢。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-07-13 17:17:44

PHP不知道它是否在文件的末尾,直到您尝试读取它。试试这个简单的例子:

代码语言:javascript
复制
<?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)不返回任何数据,而且无论您在做什么处理,都不会处理任何数据。如果你真的需要知道你是否在文件的末尾,你必须先读一遍。

票数 3
EN

Stack Overflow用户

发布于 2010-07-13 17:43:48

这可能更像是一个问题,而不是一个答案,但是为什么不使用内容()呢?根据我的经验,如果您正在读取一个文件或一个流,这个函数会为您执行脏的工作(假设您想要将整个资源读取到一个字符串,或者知道/可以计算一个限制和偏移)。它的姐妹函数file_put_contents()工作得很好,正好相反。

例如,这里有一个例子:

代码语言:javascript
复制
$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);
}

或者一条小溪:

代码语言:javascript
复制
$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
EN

Stack Overflow用户

发布于 2010-07-13 17:26:06

您关于在feof之前不调用fread的断言是不正确的,因此这个问题是无效的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3239481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档