php使用file函数、fseek函数读取大文件效率对比分析


Posted in PHP onNovember 04, 2016

php读取大文件可以使用file函数和fseek函数,但是二者之间效率可能存在差异,本文章向大家介绍php file函数与fseek函数实现大文件读取效率对比分析,需要的朋友可以参考一下。

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.直接使用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--;
    }// http://www.manongjc.com
    $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)
    {
      // 作者:码农教程  http://www.manongjc.com
      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 相关文章推荐
建站常用13种PHP开源CMS比较
Aug 23 PHP
PHP iconv 解决utf-8和gb2312编码转换问题
Apr 12 PHP
apache配置虚拟主机的方法详解
Jun 17 PHP
解析PHP对现有搜索引擎的调用
Jun 25 PHP
9个经典的PHP代码片段分享
Dec 18 PHP
PHP实现将视频转成MP4并获取视频预览图的方法
Mar 12 PHP
给WordPress的编辑后台添加提示框的代码实例分享
Dec 25 PHP
PHP通过加锁实现并发情况下抢码功能
Aug 10 PHP
mac系统下安装多个php并自由切换的方法详解
Apr 21 PHP
Laravel5.* 打印出执行的sql语句的方法
Jul 24 PHP
Yii 2.0实现联表查询加搜索分页的方法示例
Aug 02 PHP
PHP实现搜索时记住状态的方法示例
May 11 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
Nov 04 #PHP
Redis使用Eval多个键值自增的操作实例
Nov 04 #PHP
php array_slice 取出数组中的一段序列实例
Nov 04 #PHP
PHP获取访问页面HTTP状态码的实现代码
Nov 03 #PHP
PHP之将POST数据转化为字符串的实现代码
Nov 03 #PHP
PHP读取文件的常见几种方法
Nov 03 #PHP
PHP自定义多进制的方法
Nov 03 #PHP
You might like
PHP通过iconv将字符串从GBK转换为UTF8字符集
2011/07/18 PHP
PHP获取ip对应地区和使用网络类型的方法
2015/03/11 PHP
基于php的微信公众平台开发入门实例
2015/04/15 PHP
7个鲜为人知却非常实用的PHP函数
2015/07/01 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
Thinkphp 框架扩展之行为扩展原理与实现方法分析
2020/04/23 PHP
关于实现代码语法标亮 dp.SyntaxHighlighter
2007/02/02 Javascript
可实现多表单提交的javascript函数
2007/08/01 Javascript
fix-ie5.js扩展在IE5下不能使用的几个方法
2007/08/20 Javascript
javascript 限制输入脚本大全
2009/11/03 Javascript
JS中的substring和substr函数的区别说明
2013/05/07 Javascript
js实现广告漂浮效果的小例子
2013/07/02 Javascript
使用JS实现jQuery的addClass, removeClass, hasClass函数功能
2014/10/31 Javascript
不到30行JS代码实现Excel表格的方法
2014/11/15 Javascript
jQuery实现平滑滚动的标签分栏切换效果
2015/08/28 Javascript
DIV随滚动条滚动而滚动的实现代码【推荐】
2016/04/12 Javascript
vue使用vue-cli快速创建工程
2017/07/28 Javascript
vue获取DOM元素并设置属性的两种实现方法
2017/09/30 Javascript
vue实现动态按钮功能
2019/05/13 Javascript
JavaScript模块管理的简单实现方式详解
2019/06/15 Javascript
VUE前端从后台请求过来的数据进行转换数据结构操作
2020/11/11 Javascript
微信小程序实现滚动Tab选项卡
2020/11/16 Javascript
[53:52]OG vs EG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
Python中字符串的常见操作技巧总结
2016/07/28 Python
python 字符串只保留汉字的方法
2018/11/16 Python
Python脚本利用adb进行手机控制的方法
2019/07/08 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
基于h5py的使用及数据封装代码
2019/12/26 Python
基于HTML5的WebGL经典3D虚拟机房漫游动画
2017/11/15 HTML / CSS
HTML5中的网络存储实现方式
2020/04/28 HTML / CSS
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
高三毕业典礼主持词
2014/03/27 职场文书
单位工作证明范文
2014/09/14 职场文书
领导班子对照检查材料
2014/09/22 职场文书
Java基于字符界面的简易收银台
2021/06/26 Java/Android
多人盗宝《绿林侠盗》第三赛季4.5上线 跨平台实装
2022/04/03 其他游戏