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 相关文章推荐
一个程序下载的管理程序(一)
Oct 09 PHP
用php实现让页面只能被百度gogole蜘蛛访问的方法
Dec 29 PHP
用Zend Encode编写开发PHP程序
Feb 21 PHP
PHP中把stdClass Object转array的几个方法
May 08 PHP
推荐5款跨平台的PHP编辑器
Dec 25 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
Feb 12 PHP
ajax+php控制所有后台函数调用
Jul 15 PHP
两种php去除二维数组的重复项方法
Nov 04 PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
Mar 10 PHP
PHP微信PC二维码登陆的实现思路
Jul 13 PHP
PHP中危险的file_put_contents函数详解
Nov 04 PHP
php中yar框架实例用法讲解
Dec 27 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 include加载文件两种方式效率比较
2010/08/08 PHP
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
2014/07/18 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
Flash对联广告的关闭按钮讨论
2007/01/30 Javascript
JS字符串累加Array不一定比字符串累加快(根据电脑配置)
2012/05/14 Javascript
JS判断文本框内容改变事件的简单实例
2014/03/07 Javascript
jQuery中clearQueue()方法用法实例
2014/12/29 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
javascript禁止访客复制网页内容的实现代码
2015/08/05 Javascript
javascript中html字符串转化为jquery dom对象的方法
2015/08/27 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
JavaScript弹出对话框的三种方式
2016/03/23 Javascript
JS实现动态表格的添加,修改,删除功能(推荐)
2016/06/15 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
ionic组件ion-tabs选项卡切换效果实例
2016/08/27 Javascript
Javascript动画效果(2)
2016/10/11 Javascript
jquery实现点击页面回到顶部
2016/11/23 Javascript
WEB开发之注册页面验证码倒计时代码的实现
2016/12/15 Javascript
JavaScript对JSON数据进行排序和搜索
2017/07/24 Javascript
Array数组对象中的forEach、map、filter及reduce详析
2018/08/02 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
[01:11:46]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第一场 2月23日
2021/03/11 DOTA
详解Django中的form库的使用
2015/07/18 Python
python+openCV利用摄像头实现人员活动检测
2019/06/22 Python
Ubuntu+python将nii图像保存成png格式
2019/07/18 Python
django自定义模板标签过程解析
2019/12/14 Python
美国在线乐器和设备商店:Musician’s Friend
2018/07/06 全球购物
丹麦优惠购物网站:PLUSSHOP
2019/03/24 全球购物
Deichmann英国:德国鞋类零售商
2021/01/30 全球购物
Java的基础面试题附答案
2016/01/10 面试题
评析教师个人的自我评价
2014/02/19 职场文书
《狼》教学反思
2014/03/02 职场文书
初中英语教师个人工作总结
2015/02/09 职场文书
白银帝国观后感
2015/06/17 职场文书
教你怎么用python selenium实现自动化测试
2021/05/27 Python
MySQL完整性约束的定义与实例教程
2021/05/30 MySQL