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

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

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

<?php
ini_set('memory_limit', '-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data) - 1];
echo $line;
?>

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

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

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

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

3. 直接使用PHP的 fseek 来进行文件操作
这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,而是直接通过指针来操作,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的。
方法一
首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置, 再取这一行的位置,依次类推,直到找到了$num行。
#实现代码如下

<?php
$fp = fopen($file, "r");
$line = 10;
$pos = -2;
$t = " ";
$data = "";
while ($line > 0)
{while ($t != "\n"){fseek($fp, $pos, SEEK_END);$t = fgetc($fp);$pos--;}$t = " ";$data .= fgets($fp);$line--;
}
fclose($fp);
echo $data
?>

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

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

<?php
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
for ($len = 0; $len < $max; $len += $chunk)
{$seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;fseek($fp, ($len + $seekSize) * -1, SEEK_END);$readData = fread($fp, $seekSize) . $readData;if (substr_count($readData, "\n") >= $num + 1){preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match);$data = $match[0];break;}
}
fclose($fp);
echo $data;
?>

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

方法三

<?php
function tail($fp, $n, $base = 5)
{assert($n > 0);$pos = $n + 1;$lines = array();while (count($lines) <= $n){try{fseek($fp, -$pos, SEEK_END);}catch (Exception $e){fseek(0);break;}$pos *= $base;while (!feof($fp)){array_unshift($lines, fgets($fp));}}return array_slice($lines, 0, $n);
}var_dump(tail(fopen("access.log", "r+"), 10));
?>

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

方法四

PHP的stream_get_line函数 ,读取快速,读取50万条数据大文件,大概需要20秒左右的时间!例子代码如下

$fp = fopen('./iis.log', 'r'); //文件
while (!feof($fp)) { //for($j=1;$j<=1000;$j++) {         //读取下面的1000行并存储到数组中 $logarray[] = stream_get_line($fp, 65535, "\n"); // break;// }
 }

php -- 读取大文件相关推荐

  1. java 读取txt,java读取大文件

    java 读取txt,java读取大文件 package com.bbcmart.util; import java.io.File; import java.io.RandomAccessFile; ...

  2. Windows/Linux上使用fopen相关函数读取大文件

    在介绍读取大文件之前,先了解下<cstdint>文件,标准头文件,存放固定宽度整数类型,如int32_t, uint32_t,不管在32位上还是64位上,长度都为4个字节:int64_t, ...

  3. php读取大文件某行内容,php读取大文件最后几行数据的实现代码

    /* * 读取大文件最后几行数据 * by www.jbxue.com */ $file = $handledir.'/venocap.1'; $fp = fopen($file, "r&q ...

  4. pandas读取大文件(chunksize)并通过sqlalchemy写入MySQL数据库

    pandas读取大文件(chunksize)并通过sqlalchemy写入MySQL数据库 在pandas中读取表类文件的时候有一个参数chunksize,只要指定了这个参数的数值,那么得到的结果就不 ...

  5. java 按行读取大文件文件内容_Java实现按行读取大文件

    Java实现按行读取大文件 String file = "F:" + File.separator + "a.txt"; FileInputStream fis ...

  6. php yield 导出文件,PHP yield 读取大文件

    今天来优化下读取大文件,在 PHP 读取大文件的时候,经常会出现内存不足的情况,如果文件过大的话,没法一次读取完,今天采用 yield 来实现大文件的读取.yield生成器是php5.5之后出现的,y ...

  7. python读取大文件-Python如何读取、拆分大文件

    简述 最近和第三方数据接触较多,数据量也开始陡增,从一开始的1KW行,最大到了1亿行,这让我这个常年处理"小数据'的人有点捉襟见肘.本来数据放在hive中也是可以操作的,但是有时候需求是做一 ...

  8. python读取大文件-python如何读取大文件以及分析时的性能优化小技巧

    在二代.三代测序背景下,分析人员难免会遇到解析超过1G.或者10G以上的文件.这里将给大家简单介绍下如何用python读取大文件,并给大家提两个优化代码的小建议. 首先,python 读取GB级大文件 ...

  9. python读取大文件-使用Python读取大文件的方法

    背景 最近处理文本文档时(文件约2GB大小),出现memoryError错误和文件读取太慢的问题,后来找到了两种比较快Large File Reading 的方法,本文将介绍这两种读取方法. 准备工作 ...

最新文章

  1. 用集合java字符串第一个单词_Java小程序 输入一个字符串,将每一个单词首字母大写...
  2. 数据库常用操作(未完待续)
  3. javaweb基础(40)_jdbc框架
  4. 工作中常用的但是又容易忽略的问题
  5. 在闲鱼,我们如何用Dart做高效后端开发?
  6. discusz 判断当前页是门户还是论坛
  7. Linux Device Tree
  8. Apache Thrift - 可伸缩的跨语言服务开发框架
  9. Win8:Setting
  10. 学生选课系统 c语言
  11. Unity获得汉字拼音或首字母
  12. 一个有情怀的PPT模板下载网站
  13. 鼠标连点器同时点多个位置_C++自制鼠标连点器
  14. CVPR 2020 论文大盘点-去雨去雾去模糊篇
  15. Android Recovery OTA升级(二)—— Recovery源码解析
  16. 剑指offer 面试题46 python版+解析:把数字翻译成字符串
  17. 【矩阵论】单射、满射与双射
  18. 光学成像基础-荧光滤色片
  19. Mac 如何在终端玩游戏
  20. 全国智能制造(中国制造2025)创新创业大赛华北赛区决赛完美收官

热门文章

  1. [转]XPS转JPG转换器
  2. Android开发进阶之NIO非阻塞包(一)
  3. 更换ubuntu软件源的方法
  4. 数字资产交易所IM即时通讯社交系统APP开发
  5. 另一种的SQL注入和DNS结合的技巧
  6. ExtJS入门教程03,form中怎能没有validation
  7. 在“DNS管理器”中手工增加DNS主机(A)或者别名(CNAME)记录时,出现被拒绝的错误...
  8. 数论 - SGU 105 DIV3
  9. Java基础—IO流
  10. squid+iptalbes实现透明代理配置记录