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 相关文章推荐
弄了个检测传输的参数是否为数字的Function
Dec 06 PHP
在任意字符集下正常显示网页的方法二(续)
Apr 01 PHP
php正则表达匹配中文问题分析小结
Mar 25 PHP
PHP fopen 读取带中文URL地址的一点见解
Sep 25 PHP
七款最流行的PHP本地服务器分享
Feb 19 PHP
解析php中eclipse 用空格替换 tab键
Jun 24 PHP
PHP检测移动设备类mobile detection使用实例
Apr 14 PHP
php中convert_uuencode()与convert_uuencode函数用法实例
Nov 22 PHP
PHP实现搜索相似图片
Sep 22 PHP
laravel 使用事件系统统计浏览量的实现
Oct 16 PHP
php实现图片压缩处理
Sep 09 PHP
PHP7移除的扩展和SAPI
Mar 09 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 clearstatcache()函数详解
2010/03/02 PHP
php include加载文件两种方式效率比较
2010/08/08 PHP
PHP动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
十幅图告诉你什么是PHP引用
2015/02/22 PHP
php.ini中的request_order推荐设置
2015/05/10 PHP
smarty循环嵌套用法示例分析
2016/07/19 PHP
PHP图片水印类的封装
2017/07/06 PHP
PHP检查网站是否宕机的方法示例
2017/07/24 PHP
PHP实现动态压缩js与css文件的方法
2018/05/02 PHP
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
AngularJS 2.0新特性有哪些
2016/02/18 Javascript
jQuery常用的一些技巧汇总
2016/03/26 Javascript
jQuery+Pdo编写login登陆界面
2016/08/01 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
JS Testing Properties 判断属性是否在对象里的方法
2017/10/01 Javascript
使用vue-router beforEach实现判断用户登录跳转路由筛选功能
2018/06/25 Javascript
JavaScript引用类型Object常见用法实例分析
2018/08/08 Javascript
javascript实现弹幕墙效果
2019/11/28 Javascript
[02:32]DOTA2亚洲邀请赛 VG战队巡礼
2015/02/03 DOTA
Python代码调试的几种方法总结
2015/04/15 Python
Python计算字符宽度的方法
2016/06/14 Python
Python算法之图的遍历
2017/11/16 Python
Python 实现选择排序的算法步骤
2018/04/22 Python
python 的numpy库中的mean()函数用法介绍
2020/03/03 Python
Html5游戏开发之乒乓Ping Pong游戏示例(二)
2013/01/21 HTML / CSS
Tech21美国/加拿大:英国NO.1防摔保护壳品牌
2018/01/20 全球购物
餐饮主管岗位职责
2013/12/10 职场文书
大四本科生的自我评价
2013/12/30 职场文书
信息专业学生学习的自我评价
2014/02/17 职场文书
商务英语广告词大全
2014/03/18 职场文书
入党介绍人评语
2014/05/06 职场文书
会计专业应届生自荐信
2014/06/28 职场文书
大学生党员个人总结
2015/02/13 职场文书
2019年图书室自查报告范本
2019/10/12 职场文书
详细谈谈MYSQL中的COLLATE是什么
2021/06/11 MySQL