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来实现网络服务
Sep 15 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
Jun 03 PHP
PHP 读取大文件的X行到Y行内容的实现代码
Jun 24 PHP
php表单请求获得数据求和示例
May 15 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
Jun 22 PHP
PHP 导出Excel示例分享
Aug 18 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
Jan 26 PHP
9个比较实用的php代码片段
Mar 15 PHP
php+mysql查询实现无限下级分类树输出示例
Oct 03 PHP
php 广告点击统计代码(php+mysql)
Feb 21 PHP
Laravel模型事件的实现原理详解
Mar 14 PHP
PHP使用ajax的post方式下载excel文件简单示例
Aug 06 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获取网站域名和地址的代码
2008/08/17 PHP
php实现图片添加水印功能
2014/02/13 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
php生成随机颜色方法汇总
2014/12/03 PHP
Yii2中DropDownList简单用法示例
2016/07/18 PHP
Yii框架函数简单用法分析
2019/09/09 PHP
laravel 解决crontab不执行的问题
2019/10/22 PHP
Jquery 插件开发笔记整理
2011/01/17 Javascript
利用cookie记住背景颜色示例代码
2013/11/04 Javascript
fmt:formatDate的输出格式详解
2014/01/09 Javascript
详述JavaScript实现继承的几种方式(推荐)
2016/03/22 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
jQuery实现为动态添加的元素绑定事件实例分析
2018/09/07 jQuery
JavaScript遍历数组的三种方法map、forEach与filter实例详解
2019/02/27 Javascript
axios+Vue实现上传文件显示进度功能
2019/04/14 Javascript
js实现随机8位验证码
2020/07/24 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
JQuery省市联动效果实现过程详解
2020/05/08 jQuery
详解实现vue的数据响应式原理
2021/01/20 Vue.js
python概率计算器实例分析
2015/03/25 Python
浅谈Python中列表生成式和生成器的区别
2015/08/03 Python
Python中http请求方法库汇总
2016/01/06 Python
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
快速查询Python文档方法分享
2017/12/27 Python
python 实现数组list 添加、修改、删除的方法
2018/04/04 Python
Flask入门之上传文件到服务器的方法示例
2018/07/18 Python
对python多线程中互斥锁Threading.Lock的简单应用详解
2019/01/11 Python
pyqt5 实现在别的窗口弹出进度条
2019/06/18 Python
详解python metaclass(元类)
2020/08/13 Python
Python利用pip安装tar.gz格式的离线资源包
2020/09/14 Python
python3访问字典里的值实例方法
2020/11/18 Python
大学学风建设方案
2014/05/04 职场文书
社区务虚会发言材料
2014/10/20 职场文书
英语辞职信范文
2015/02/28 职场文书
2015年度保密工作总结
2015/04/24 职场文书