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 相关文章推荐
ip签名探针
Oct 09 PHP
如何实现给定日期的若干天以后的日期
Oct 09 PHP
PHP操作数组相关函数
Feb 03 PHP
PHP警告Cannot use a scalar value as an array的解决方法
Jan 11 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
Jun 19 PHP
php+xml编程之SimpleXML的应用实例
Jan 24 PHP
24条货真价实的PHP代码优化技巧
Jul 28 PHP
php微信开发接入
Aug 27 PHP
php cookie用户登录的详解及实例代码
Jan 03 PHP
PHP简单留言本功能实现代码
Jun 09 PHP
php中青蛙跳台阶的问题解决方法
Oct 14 PHP
php实现断点续传大文件示例代码
Jun 19 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+DBM的同学录程序(1)
2006/10/09 PHP
发一个php简单的伪原创程序,配合商城采集用的
2010/10/12 PHP
php学习之运算符相关概念
2011/06/09 PHP
php版微信自动获取收货地址api用法示例
2016/09/22 PHP
php实现批量上传数据到数据库(.csv格式)的案例
2017/06/18 PHP
浏览器兼容console对象的简要解决方案分享
2013/10/24 Javascript
JavaScript事件委托用法分析
2015/01/24 Javascript
js的for in循环和java里foreach循环的区别分析
2015/01/28 Javascript
JavaScript数组对象实现增加一个返回随机元素的方法
2015/07/27 Javascript
Javascript 实现微信分享(QQ、朋友圈、分享给朋友)
2016/10/21 Javascript
深入理解jquery中的each用法
2016/12/14 Javascript
Node.js利用Net模块实现多人命令行聊天室的方法
2016/12/23 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
2017/03/19 Javascript
JavaScript实现HTML5游戏断线自动重连的方法
2017/09/18 Javascript
详解如何使用webpack打包JS
2018/06/21 Javascript
js实现动态添加上传文件页面
2018/10/22 Javascript
webpack的pitching loader详解
2019/09/23 Javascript
浅析Vue下的components模板使用及应用
2019/11/27 Javascript
js实现超级玛丽小游戏
2020/03/18 Javascript
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
python3中bytes和string之间的互相转换
2017/02/09 Python
Python中的命令行参数解析工具之docopt详解
2017/03/27 Python
基于python list对象中嵌套元组使用sort时的排序方法
2018/04/18 Python
Django利用cookie保存用户登录信息的简单实现方法
2019/05/27 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
Python字典常见操作实例小结【定义、添加、删除、遍历】
2019/10/25 Python
Python BeautifulReport可视化报告代码实例
2020/04/13 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
基于CSS3实现的几个小loading效果
2018/09/27 HTML / CSS
HTML5 input placeholder 颜色修改示例
2014/05/30 HTML / CSS
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
美国孩之宝玩具官网:Hasbro Pulse
2019/06/24 全球购物
企业申诉管理制度
2014/01/30 职场文书
旺仔牛奶广告词
2014/03/20 职场文书
大学生见习总结报告
2015/06/24 职场文书
解决Redis启动警告问题
2022/02/24 Redis