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 相关文章推荐
PHP个人网站架设连环讲(二)
Oct 09 PHP
深入PHP获取随机数字和字母的方法详解
Jun 06 PHP
php操作MongoDB基础教程(连接、新增、修改、删除、查询)
Mar 25 PHP
教你如何在CI框架中使用 .htaccess 隐藏url中index.php
Jun 09 PHP
ThinkPHP自动完成中使用函数与回调方法实例
Nov 29 PHP
php删除左端与右端空格的方法
Nov 29 PHP
PHP strtotime函数用法、实现原理和源码分析
Feb 04 PHP
php的4种常见运行方式
Mar 20 PHP
PHPStrom中实用的功能和快捷键大全
Sep 23 PHP
PHP 绘制网站登录首页图片验证码
Apr 12 PHP
原生php实现excel文件读写的方法分析
Apr 25 PHP
phpinfo的知识点总结
Oct 10 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如何将XML转成数组
2016/04/04 PHP
ThinkPHP5.1验证码功能实现的示例代码
2020/06/08 PHP
无阻塞加载脚本分析[全]
2011/01/20 Javascript
jQuery监控文本框事件并作相应处理的方法
2015/04/16 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
js实现一个可以兼容PC端和移动端的div拖动效果实例
2016/12/09 Javascript
DOM事件探秘篇
2017/02/15 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
js轮播图透明度切换(带上下页和底部圆点切换)
2017/04/27 Javascript
JS对象与JSON互转换、New Function()、 forEach()、DOM事件流等js开发基础小结
2017/08/10 Javascript
JavaScript面向对象精要(上部)
2017/09/12 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
vue实现文件上传功能
2018/08/13 Javascript
Vue用v-for给循环标签自身属性添加属性值的方法
2018/10/18 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
2019/02/21 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
2019/04/26 Javascript
vue 实现锚点功能操作
2020/08/10 Javascript
[01:14:19]NAVI vs Mineski 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
python数据结构之二叉树的遍历实例
2014/04/29 Python
Python程序中用csv模块来操作csv文件的基本使用教程
2016/03/03 Python
Python中进程和线程的区别详解
2017/10/29 Python
Python多线程原理与用法详解
2018/08/20 Python
Python matplotlib画图与中文设置操作实例分析
2019/04/23 Python
使用Python opencv实现视频与图片的相互转换
2019/07/08 Python
Python实现简单的列表冒泡排序和反转列表操作示例
2019/07/10 Python
django中瀑布流写法实例代码
2019/10/14 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
英国知名的皮手套品牌:Dents
2016/11/13 全球购物
英国豪华针织品牌John Smedley的在线销售商:The Outlet by John Smedley
2018/04/08 全球购物
宣传策划类求职信范文
2014/01/31 职场文书
外贸专业求职信
2014/03/09 职场文书
2014普法依法治理工作总结
2014/12/18 职场文书
房地产财务经理岗位职责
2015/04/08 职场文书
2015年秋季开学典礼校长致辞
2015/07/16 职场文书
mysql知识点整理
2021/04/05 MySQL
opencv检测动态物体的实现
2021/07/21 Python