PHP如何快速读取大文件

原文:PHP如何快速读取大文件

在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能 很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。

需求需求

有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容。

实现方法

1. 直接采用file函数来操作

由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的 memory_limit = 16M 来进行设置,这个值如果设置-1,则内存使用量不受限制。

下面是一段用file来取出这具文件最后一行的代码:

1    <?php
2    ini_set(‘memory_limit‘, ‘-1‘);
3    $file = ‘access.log‘;
4    $data = file($file);
5    $line = $data[count($data) - 1];
6    echo $line;
7    ?>

整个代码执行完成耗时 116.9613 (s)。

我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万 不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了。

2.直接调用Linux的 tail 命令来显示最 后几行

在Linux命令行下,可以直接使用 tail -n 10 access.log 很轻易的显示日志文件最后几行,可以直接用PHP来调用tail命令,执行PHP代码如下:

1    <?php
2    $file = ‘access.log‘;
3    $file = escapeshellarg($file); // 对命令行参数进行安全转义
4    $line = `tail -n 1 $file`;
5    echo $line;
6    ?>

整个代码执行完成耗时 0.0034 (s)

3. 直接使用PHP的 fseek 来进行文件操作

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,而是直接通过指针来操作,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法:

方法一

首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置, 再取这一行的位置,依次类推,直到找到了$num行。

#实现代码如下

01    <?php
02    $fp = fopen($file, "r");
03    $line = 10;
04    $pos = -2;
05    $t = " ";
06    $data = "";
07    while ($line > 0)
08    {
09        while ($t != "\n")
10        {
11            fseek($fp, $pos, SEEK_END);
12            $t = fgetc($fp);
13            $pos--;
14        }
15        $t = " ";
16        $data .= fgets($fp);
17        $line--;
18    }
19    fclose($fp);
20    echo $data
21    ?>

整个代码执行完成耗时 0.0095 (s)

方法二

还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换 行符(\n)的个数来判断是否已经读完最后$num行数据。

#实现代码如下

01    <?php
02    $fp = fopen($file, "r");
03    $num = 10;
04    $chunk = 4096;
05    $fs = sprintf("%u", filesize($file));
06    $max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
07    for ($len = 0; $len < $max; $len += $chunk)
08    {
09        $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
10        fseek($fp, ($len + $seekSize) * -1, SEEK_END);
11        $readData = fread($fp, $seekSize) . $readData;
12        if (substr_count($readData, "\n") >= $num + 1)
13        {
14            preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match);
15            $data = $match[0];
16            break;
17        }
18    }
19    fclose($fp);
20    echo $data;
21    ?>

整个代码执行完成耗时 0.0009(s)。

方法三

01    <?php
02    function tail($fp, $n, $base = 5)
03    {
04        assert($n > 0);
05        $pos = $n + 1;
06        $lines = array();
07        while (count($lines) <= $n)
08        {
09            try
10            {
11                fseek($fp, -$pos, SEEK_END);
12            }
13            catch (Exception $e)
14            {
15                fseek(0);
16                break;
17            }
18            $pos *= $base;
19            while (!feof($fp))
20            {
21                array_unshift($lines, fgets($fp));
22            }
23        }
24
25        return array_slice($lines, 0, $n);
26    }
27
28    var_dump(tail(fopen("access.log", "r+"), 10));
29    ?>

整个代码执行完成耗时 0.0003(s)

时间: 2024-10-30 22:37:22

PHP如何快速读取大文件的相关文章

PHP几个快速读取大文件例子

PHP几个快速读取大文件例子 感谢 把我给崩了 的投递 时间:2014-10-16 来源:三联 在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file.file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能.但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法. 需求 有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容. 实现方法 1. 直接采

【转】PHP如何快速读取大文件

在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file.file_get_contents之类的函数,简简单单的几行代码就能 很漂亮的完成我们所需要的功能.但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法. 需求需求 有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容. 实现方法 1. 直接采用file函数来操作 由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写

快速读取大文件的几种方式

转一篇:http://blog.csdn.net/fengxingzhe001/article/details/67640083 原来使用一行一行读取文本的方式,速度是慢的的可以,弄了好久还是不行,后来看了下才知道要用字节流传输会快很多 我自己也测了一下80M的文件,发现给读入块的大小会很明显的影响读入的速度. 测试代码如下: def useBufferIStream(): Util = { try { val begin = System.currentTimeMillis val file

java快速读取大文件

private String FileSeparator = File.separator; //区别不同window平台目录分隔符 private String FilePath = "E:"+FileSeparator+"Code"+FileSeparator+"pdm-server-parent"+FileSeparator+"pdm-server"+FileSeparator+"logs"; pri

Java高效读取大文件

1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 这种

Java高效读取大文件(转)

1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung(http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: 1 2 3 Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)

php -- 读取大文件

在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file.file_get_contents之类的函数,简简单单的几行代码就能 很漂亮的完成我们所需要的功能.但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法. 需求需求有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容. 实现方法1. 直接采用file函数来操作由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写的比较

Java读取大文件的高效率实现

1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 这种

linux 快速生成大文件

快速生成大文件 命令一: truncate -s 10G test4 命令二: dd if=/home/sina.html of=/home/mms0.txt bs=1024 count=1 if的参数是输入文件是新浪的主页, of的参数是要生成的文件, bs的参数是每次读入的block大小,这里就设为要生成的文件大小, count的参数是读取的block个数,这里就设为1. 原文地址:https://www.cnblogs.com/tomtellyou/p/12257554.html