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数组实现无限分类,不使用数据库,不使用递归.
Dec 09 PHP
php利用iframe实现无刷新文件上传功能的代码
Sep 29 PHP
Zend Studio去除编辑器的语法警告设置方法
Oct 24 PHP
解析PHP中数组元素升序、降序以及重新排序的函数
Jun 20 PHP
Linux下PHP安装mcrypt扩展模块笔记
Sep 10 PHP
PHP @ at 记号的作用示例介绍
Oct 10 PHP
php实现图片局部打马赛克的方法
Feb 11 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
Feb 15 PHP
php使用自定义函数实现汉字分割替换功能示例
Jan 30 PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
Nov 08 PHP
PHP格式化显示时间date()函数代码
Oct 03 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+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
phpMyAdmin 链接表的附加功能尚未激活问题的解决方法(已测)
2012/03/27 PHP
PHP函数preg_match_all正则表达式的基本使用详细解析
2013/08/31 PHP
yii插入数据库防并发的简单代码
2017/05/27 PHP
thinkphp3.2同时连接两个数据库的简单方法
2019/08/13 PHP
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
2013/11/22 Javascript
Javascript和Java获取各种form表单信息的简单实例
2014/02/14 Javascript
jQuery操作select下拉框的text值和value值的方法
2014/05/31 Javascript
使用Nodejs开发微信公众号后台服务实例
2014/09/03 NodeJs
JavaScript中的console.group()函数详细介绍
2014/12/29 Javascript
解决jQuery上传插件Uploadify出现Http Error 302错误的方法
2015/12/18 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
详解cordova打包成webapp的方法
2017/10/18 Javascript
Vue兼容ie9的问题全面解决方案
2018/06/19 Javascript
详解如何在nuxt中添加proxyTable代理
2018/08/10 Javascript
layerUI下的绑定事件实例代码
2018/08/17 Javascript
Vue高版本中一些新特性的使用详解
2018/09/25 Javascript
微信小程序扫描二维码获取信息实例详解
2019/05/07 Javascript
Python中使用SAX解析xml实例
2014/11/21 Python
python简单判断序列是否为空的方法
2015/06/30 Python
利用python解决mysql视图导入导出依赖的问题
2017/12/17 Python
浅谈Pycharm调用同级目录下的py脚本bug
2018/12/03 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
python 实现两个npy档案合并
2020/07/01 Python
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
技校教师求职简历的自我评价
2013/10/20 职场文书
人事行政主管岗位职责
2013/12/22 职场文书
酒店经理职责
2014/01/30 职场文书
股指期货心得体会
2014/09/10 职场文书
2014国庆节国旗下演讲稿(精选版)
2014/09/26 职场文书
预备党员2014年第四季度思想汇报范文
2014/10/25 职场文书
辞职信格式模板
2015/02/27 职场文书
大学生读书笔记范文
2015/07/01 职场文书
浅谈Redis缓冲区机制
2022/06/05 Redis
CSS元素定位之通过元素的标签或者元素的id、class属性定位详解
2022/09/23 HTML / CSS