前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3分钟短文 | 大神救我!18G的大文件,PHP咋按行读取?

3分钟短文 | 大神救我!18G的大文件,PHP咋按行读取?

作者头像
程序员小助手
发布2020-06-19 14:55:30
1.2K0
发布2020-06-19 14:55:30
举报
文章被收录于专栏:程序员小助手程序员小助手

引言

想逐行读取文件,完全避免把这个文件加载到内存中。如果文件太大(比如 18G),无法在内存中打开,还是要硬来的话,会抛出异常。

大小的编程语言都提供了文件的按行读写,PHP 怎会没有!

正确方法

是不能够使用 file_get_contents 函数,一股脑把所有文件内容扔到内存的。应该使用 fgets 函数逐行读取:

代码语言:javascript
复制
$handle = fopen("inputfile.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        // process the line read.
    }

    fclose($handle);
} else {
    // error opening the file.
}

首先打开文件句柄,然后逐行使用 fgets 读取,处理完毕后使用 fclose 显式关闭。

当然,你也可以不必使用 false 判断,转而使用 feof 检测是否到文件末尾即可:

代码语言:javascript
复制
if ($file = fopen("file.txt", "r")) {
    while(!feof($file)) {
        $line = fgets($file);
        # do same stuff with the $line
    }
    fclose($file);
}

所谓“条条大道通罗马”,实现功能的方法不止一种。我们更推荐的是下面的这种写法。使用 PHP 5.1 之后提供的 SplFileObject 对象处理文件。

那么就可以这样写:

代码语言:javascript
复制
$file = new SplFileObject("file.txt");

// Loop until we reach the end of the file.
while (!$file->eof()) {
    // Echo one line from the file.
    echo $file->fgets();
}

// Unset the file to call __destruct(), closing the file handle.
$file = null;

这个对象提供了为数众多的方法用于文件操作:

比起我们常用的一些文件操作函数:

  • fgetss() - 从文件指针中读取一行并过滤掉 HTML 标记
  • fread() - 读取文件(可安全用于二进制文件)
  • fgetc() - 从文件指针中读取字符
  • stream_get_line() - 从资源流里读取一行直到给定的定界符
  • fopen() - 打开文件或者 URL
  • popen() - 打开进程文件指针
  • fsockopen() - 打开一个网络连接或者一个Unix套接字连接
  • stream_set_timeout() - Set timeout period on a stream

SplFileObject 对象封装的更为灵活,如果嵌入到程序内使用,可以组装为十分强大的文件操作类。比一个个的操作函数,有更强的可扩展性。

写在最后

通过一个大文件的按行读取,我们引出了 SplFileObject 这个文件操作对象,希望大家仔细地学习一下,可以大大提升功力。

Happy coding :_)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小助手 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 正确方法
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档