PHP feof() 在文件结束前返回 true

标签 php fopen fgets feof

最近几天我一直在处理一个奇怪的 PHP 问题,feof() 函数在文件结束之前返回 true。下面是我的代码的框架:

$this->fh = fopen("bigfile.txt", "r");    

while(!feof($this->fh))
{
    $dataString = fgets($this->fh);

    if($dataString === false && !feof($this->fh))
    {
        echo "Error reading file besides EOF";
    }
    elseif($dataString === false && feof($this->fh))
    {
        echo "We are at the end of the file.\n";

        //check status of the stream
        $meta = stream_get_meta_data($this->fh);
        var_dump($meta);
    }
    else
    {
        //else all is good, process line read in 
    }
}

通过大量测试,我发现该程序在除一个文件外的所有方面都运行良好:

  • 文件存储在本地驱动器上。
  • 此文件长约 800 万行,平均每行约 200-500 个字符。
  • 已经清理干净,并用十六进制编辑器仔细检查,没有发现异常字符。
  • 当程序认为它已到达文件末尾(即使它还剩下约 800K 行)时,它始终在第 7172714 行失败。
  • 我已经在每行字符数较少但在 20-30 百万行之间的文件上测试了该程序,没有任何问题。
  • 我尝试从 http://php.net/manual/en/function.fgets.php 上的评论运行代码只是为了看看是不是我的代码中的某些东西导致了这个问题,而第 3 方代码在同一行上失败了。编辑:还值得一提的是,第 3 方代码使用 fread() 而不是 fgets()。
  • 我尝试在 fgets 函数中指定多个缓冲区大小,但没有任何区别。

var_dump($meta) 的输出如下:

 array(9) {
  ["wrapper_type"]=>
  string(9) "plainfile"
  ["stream_type"]=>
  string(5) "STDIO"
  ["mode"]=>
  string(1) "r"
  ["unread_bytes"]=>
  int(0)
  ["seekable"]=>
  bool(true)
  ["uri"]=>
  string(65) "full path of file being read"
  ["timed_out"]=>
  bool(false)
  ["blocked"]=>
  bool(true)
  ["eof"]=>
  bool(true)
}

在试图找出导致 feof 在文件末尾之前返回 true 的原因时,我不得不猜测:

A) 某事导致 fopen 流失败,然后无法读取任何内容(导致 feof 返回 true)

B)某处有一些缓冲区正在填满并造成破坏

C) PHP 大神们生气了

我进行了广泛的搜索,看看是否还有其他人遇到过这个问题,但找不到任何实例,除了在 C++ 中,文件是通过文本模式而不是二进制模式读取并导致问题的。

更新: 我让我的脚本不断输出读取函数迭代的次数以及与它在旁边找到的条目关联的用户的唯一 ID。该脚本在第 7175502 行中的第 7172713 行之后仍然失败,但文件中最后一个用户的唯一 ID 显示在第 7172713 行上。问题似乎是由于某些原因,行被跳过且未被读取。所有换行符都存在。

最佳答案

你必须分割你的文件或增加 php 的超时时间 通过:

upload_max_filesize = 2M 
;or whatever size you want

最大执行时间 = 60 ;另外,如果必须的话,更高

因为: 如果文件指针位于 EOF 或发生错误(包括套接字超时),则返回 TRUE;否则返回 FALSE。 参见:http://php.net/manual/en/function.feof.php

关于PHP feof() 在文件结束前返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27936220/

相关文章:

C编程: how to fopen a designated file and dynamically allocate its contents into a 2D array?

c - 用 C 打开和读取文件

C++ 使用 fgets 读取另一行

c - scanf 之后 fgets 不起作用

javascript - 已删除的文件仍在被访问

php - MySQL 日期格式(德语)

php - SHA-1 哈希可以是纯数字吗?

php - 无法将输入投票数更新到我的数据库中

C - 当我使用 fopen() 创建文件时,该文件位于哪里?

c - 在c/cocoa中读取和输出UTF-8字符串