在 PHP 中读取非常大的文件

2022-08-30 15:31:30

fopen当我尝试读取 中大小适中的文件时,失败。 使它窒息,尽管周围较小的文件就好了。我已经读到,有时有必要重新编译标志,以便读取超过20 gigs或荒谬的文件,但是我不应该对6 meg文件没有问题吗?最终,我们将希望读取大约100兆的文件,并且能够打开它们然后使用fgts逐行读取它们会很好,就像我能够对较小的文件所做的那样。PHPA 6 meg file100kPHP-D_FILE_OFFSET_BITS=64

您在 中读取和操作非常大的文件有哪些技巧/解决方案?PHP

更新:这是一个简单的代码块示例,在我的6 meg文件上失败 - PHP似乎没有抛出错误,它只是返回false。也许我正在做一些非常愚蠢的事情?

$rawfile = "mediumfile.csv";

if($file = fopen($rawfile, "r")){  
  fclose($file);
} else {
  echo "fail!";
}

另一个更新:感谢大家的帮助,它确实被证明是非常愚蠢的 - 权限问题。我的小文件莫名其妙地具有读取权限,而较大的文件没有。哎呀!


答案 1

您确定是失败的,而不是脚本的超时设置吗?默认值通常约为 30 秒左右,如果文件读取时间超过此时间,则可能会将其跳闸。fopen

要考虑的另一件事可能是脚本上的内存限制 - 将文件读入数组可能会超过此限制,因此请检查错误日志中是否有内存警告。

如果上述两者都不是您的问题,您可以考虑使用fgets逐行读取文件,并随时进行处理。

$handle = fopen("/tmp/uploadfile.txt", "r") or die("Couldn't get handle");
if ($handle) {
    while (!feof($handle)) {
        $buffer = fgets($handle, 4096);
        // Process buffer here..
    }
    fclose($handle);
}

编辑

PHP似乎没有抛出错误,它只是返回false。

要更正的路径是否相对于脚本的运行位置?也许可以尝试在此处为文件名设置绝对路径。$rawfile


答案 2

对1.3GB文件和9.5GB文件进行了2次测试。

1.3 千兆字节

使用 fopen()

此过程使用 15555 毫秒进行计算。

它在系统调用中花费了 169 毫秒。

使用 file()

此过程使用 6983 毫秒进行计算。

它在系统调用中花费了 4469 毫秒。

9.5 千兆字节

使用 fopen()

此过程使用113559毫秒进行计算。

它在系统调用中花费了 2532 毫秒。

使用 file()

此过程使用 8221 毫秒进行计算。

它在系统调用中花费了 7998 毫秒。

似乎更快。file()


推荐