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使用者状态管理功能的应用
Oct 09 PHP
php中filter函数验证、过滤用户输入的数据
Jan 13 PHP
ThinkPHP分页类使用详解
Mar 05 PHP
使用php语句将数据库*.sql文件导入数据库
May 05 PHP
PHP中的gzcompress、gzdeflate、gzencode函数详解
Jul 29 PHP
PHP中使用php://input处理相同name值的表单数据
Feb 03 PHP
php递归调用删除数组空值元素的方法
Apr 28 PHP
大家都应该掌握的PHP关联数组使用技巧
Dec 25 PHP
PHP实现简单ajax Loading加载功能示例
Dec 28 PHP
PHP中关键字interface和implements详解
Jun 14 PHP
浅析PHP开发规范
Feb 05 PHP
laravel-admin的图片删除实例
Sep 30 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 at(@)符号的用法简介
2009/07/11 PHP
php开启安全模式后禁用的函数集合
2011/06/26 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
2013/06/06 PHP
php网站被挂木马后的修复方法总结
2014/11/06 PHP
基于laravel where的高级使用方法
2019/10/10 PHP
JavaScript 基础知识 被自己遗忘的
2009/10/15 Javascript
jQuery 源码分析笔记(3) Deferred机制
2011/06/19 Javascript
JS实现点击下载的小例子
2013/07/10 Javascript
js设置文本框中焦点位置在最后的示例代码(简单实用)
2014/03/04 Javascript
jQuery处理图片加载失败的常用方法
2015/06/08 Javascript
基于jquery实现复选框全选,反选,全不选等功能
2015/10/16 Javascript
jQuery根据name属性进行查找的用法分析
2016/06/23 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
node puppeteer(headless chrome)实现网站登录
2018/05/09 Javascript
微信小程序scroll-x失效的完美解决方法
2018/07/18 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
2019/03/20 Javascript
深入理解基于vue-cli的webpack打包优化实践及探索
2019/10/14 Javascript
让你30分钟快速掌握vue3教程
2020/10/26 Javascript
[01:34]DOTA2 7.22版本新增神杖效果一览(敏捷英雄篇)
2019/05/28 DOTA
Python BS4库的安装与使用详解
2018/08/08 Python
解决PyCharm import torch包失败的问题
2018/10/13 Python
分享Python切分字符串的一个不错方法
2018/12/14 Python
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
Ticketmaster意大利:音乐会、节日、艺术和剧院的官方门票
2019/12/23 全球购物
什么是GWT的Entry Point
2013/08/16 面试题
生物化学研究助理员求职信
2013/10/09 职场文书
建筑项目策划书
2014/01/13 职场文书
上海世博会口号
2014/06/19 职场文书
初中同学会活动方案
2014/08/22 职场文书
个人政风行风自查自纠报告
2014/10/21 职场文书
2015年学雷锋活动总结
2015/02/06 职场文书
学校党支部公开承诺书
2015/04/30 职场文书
护理培训心得体会
2016/01/22 职场文书
未来,这5大方向都很适合创业
2019/07/22 职场文书
小程序wx.getUserProfile接口的具体使用
2021/06/02 Javascript
动作冒险《Hell Is Us》将采用虚幻5 消灭怪物探索王国
2022/04/13 其他游戏