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来检测proxy
Oct 09 PHP
MYSQL数据库初学者使用指南
Nov 16 PHP
php基础知识:类与对象(3) 构造函数和析构函数
Dec 13 PHP
PHP获取数组中某元素的位置及array_keys函数应用
Jan 29 PHP
十幅图告诉你什么是PHP引用
Feb 22 PHP
浅谈PHP中关于foreach使用引用变量的坑
Nov 14 PHP
PHPMailer发送邮件
Dec 28 PHP
php实现微信支付之现金红包
May 30 PHP
Thinkphp5 如何隐藏入口文件index.php(URL重写)
Oct 16 PHP
Laravel 解决419错误 -ajax请求错误的问题(CSRF验证)
Oct 25 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
Mar 27 PHP
PHP延迟静态绑定使用方法实例解析
Sep 05 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
MySQL的FIND_IN_SET函数使用方法分享
2012/03/27 PHP
PHP截取IE浏览器并缩小原图的方法
2016/03/04 PHP
thinkphp整合微信支付代码分享
2016/11/24 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
JavaScript 面向对象之命名空间
2010/05/04 Javascript
jQuery版Tab标签切换
2011/03/16 Javascript
JavaScript中prototype为对象添加属性的误区介绍
2013/10/15 Javascript
js 绑定键盘鼠标事件示例代码
2014/02/12 Javascript
NodeJS和BootStrap分页效果的实现代码
2016/11/07 NodeJs
ES6中Generator与异步操作实例分析
2017/03/31 Javascript
Iphone手机、安卓手机浏览器控制默认缩放大小的方法总结(附代码)
2017/08/18 Javascript
Node.js 使用request模块下载文件的实例
2018/09/05 Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
2019/05/10 Javascript
如何使用CSS3和JQuery easing 插件制作绚丽菜单
2019/06/18 jQuery
JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析
2020/02/12 Javascript
vue3.0中setup使用(两种用法)
2020/12/02 Vue.js
Python中使用异常处理来判断运行的操作系统平台方法
2015/01/22 Python
python轻松实现代码编码格式转换
2015/03/26 Python
深入解析Python中的集合类型操作符
2015/08/19 Python
Python3多目标赋值及共享引用注意事项
2019/05/27 Python
python实现拼接图片
2020/03/23 Python
django model通过字典更新数据实例
2020/04/01 Python
Opencv图像处理:如何判断图片里某个颜色值占的比例
2020/06/03 Python
python文件排序的方法总结
2020/09/13 Python
新奇的小玩意:IWOOT
2016/07/21 全球购物
Foreo国际站:Foreo International
2018/10/29 全球购物
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
高中生职业生涯规划书
2014/02/24 职场文书
任命书模板
2014/06/04 职场文书
市场营销专业求职信
2014/06/17 职场文书
材料化学专业求职信
2014/07/15 职场文书
中学社团活动总结
2015/05/07 职场文书
格林童话读书笔记
2015/06/30 职场文书
2015年政治教研组工作总结
2015/07/22 职场文书
Python 流媒体播放器的实现(基于VLC)
2021/04/28 Python
2021年国产动漫公司排行前十名,玄机科技上榜,第二推出过铠甲勇士
2022/03/18 杂记