PHP读取大文件的几种方法介绍

读取大文件一直是一个头痛的问题,我们像使用php开发读取小文件可以直接使用各种函数实现,但一到大文章就会发现常用的方法是无法正常使用或时间太长太卡了,下面我们就一起来看看关于php读取大文件问题解决办法,希望例子能帮助到各位。

场景:PHP读取超大文件,例如1G的日志文件,我这里使用的是400M的access.log文件

1、使用file直接读取

<?php
$starttime=microtime_float();

ini_set('memory_limit', '-1');
$file = 'testfile.txt';

$data = file($file);
$line = $data[count($data) - 1000];
$endtime=microtime_float();

echo count($data),"<br/>";
echo $endtime-$starttime;

function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

运行结果:10127784 行   共使用了,7.8764359951s

我的电脑是3G内存,此方法不是推荐使用,因为需要把文件全部载入内存

2、使用linux命令  tail

<?php

$starttime=microtime_float();

$file = 'testfile.txt';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 100 $file`;

echo $line,"<br/>";

$endtime=microtime_float();
echo $endtime-$starttime;

function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}

//end

运行结果:只使用了几毫秒、轻松搞定、这种方法不能在windows下使用

3、使用fseek函数

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,因为PHP是C写的,所以实现的时候也类似C读取文件,通过指针的移动,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,

下面是常用的几种方法

方法一:使用fopen打开文件(从文件指针资源句柄)

<?php
$starttime=microtime_float();

$file = 'testfile.txt';
$fp = fopen($file, "r+");

$line = 100;
$pos = -2;
$t =$data="";

while ($line > 0)
{
 while ($t != "\n") //换行符
 {
 fseek($fp, $pos, SEEK_END);//移动指针
 $t = fgetc($fp);//获取一个字符
 $pos--;//向前偏移
 }

 $t = "";
 $data = fgets($fp);//获取当前行的数据
 $line--;
}
fclose($fp);
echo $data,"<br/>";
$endtime=microtime_float();

echo $endtime-$starttime;

function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

运行结果:0.338493108749

方法二:一块一块的读取

<?php
$starttime=microtime_float();

$file = 'testfile.txt';
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;//4K的块
$fs = sprintf("%u", filesize($file));
$readData='';
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : $fs;

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) {

 $ns=substr_count($readData, "\n")-$num+2;
 preg_match('/(.*?\n){'.$ns.'}/',$readData,$match);
 $data = $match[1];
 break;
}
}
fclose($fp);
echo $data,"<br/>";

$endtime=microtime_float();

echo $endtime-$starttime;

function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

运行时间:0.00199198722839

使用fgets函数,一行一行读取

<?php
$file = fopen("testfile.txt","r");
 while(!feof($file))
 {
   echo fgets($file);
 }
 fclose($file);

spl库函数

<?php
try{
  foreach( new SplFileObject('testfile.txt') as $line)
  echo $line.'<br />';
}catch (Exception $e){
  echo $e->getMessage();
}

另外网上有很多按照块读取文件的,有兴趣的读者可以试试,我试了没成功,好像必须含有换行符“\n”才可以。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • php中的路径问题与set_include_path使用介绍

    first: php中常用的路径 当前文件路径:D:\phpweb\php_example\include_path.php 复制代码 代码如下: 1.dirname(__FILE__); //输出D:\phpweb\php_example 2.$_SERVER['SCRIPT_FILENAME']; //输出D:/phpweb/php_example/include_path.php second: php中的set_include_path 在php中,include文件时,当包含路径不为相

  • PHP下的浮点运算不准的解决方法

    最近在做一个?的相加减问题是,出现了浮点运算不准的情况,看来都说解释型语言对于浮点运算都会有问题的说法是真的. 首先看一段代码: <?php $a = 0.1; $b = 0.7; var_dump(($a + $b) == 0.8); 打印出来的值居然为 boolean false 这是为啥?PHP手册对于浮点数有以下警告信息: Warning 浮点数精度 显然简单的十进制分数如同 0.1 或 0.7 不能在不丢失一点点精度的情况下转换为内部二进制的格式.这就会造成混乱的结果:例如,floor

  • PHP中set_include_path()函数相关用法分析

    本文实例讲述了PHP中set_include_path()函数相关用法.分享给大家供大家参考,具体如下: 先看如下代码: <?php /** 定义根目录 */ define('__TYPECHO_ROOT_DIR__', dirname(__FILE__)); /** 定义插件目录(相对路径) */ define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins'); /** 设置包含路径 */ @set_include_path(get_include_path(

  • php mysql like 实现多关键词搜索的方法

    或者叫,分词检索数据库 $res = mysql_query("select * from peter where id like '%中草药%' and '%6%'"); //这样写是报错的: $res = mysql_query("select * from peter where id like '%中草药%' or '%6%'"); //而这样写是正确的:奇怪~ $res = mysql_query("select * from peter whe

  • 遍历指定目录,并存储目录内所有文件属性信息的php代码

    项目需要,需要写一个函数,能够遍历指定目录中的所有文件,而且这个目录中的子目录也要遍历.输出文件的属性信息,并存储. 想想需求,不就是一个ls -al命令吗,实现获取相关属性就好了,再加上一个遍历OK了事. 项目过程中,便于操作,使用了json格式存储,但是也发现了一些问题.谨此记录问题及代码,便于参考. <?php define('INDEXFORMAT',"dir,name,size,perms,ower,group,ctime,mtime,atime,suffix") ;

  • php通过PHPExcel导入Excel表格到MySQL数据库的简单实例

    如下所示: <?php define('BASE_URL', realpath(dirname(__FILE__))); require_once BASE_URL . '/PHPExcel/PHPExcel.php';//引入PHPExcel类文件 //excel文件的地址 $excel_fiel_path = './phpexcel.xls'; $PHPExcel = new PHPExcel();// 实例化PHPExcel工具类 //分析文件获取后缀判断是2007版本还是2003 $ex

  • php set_include_path函数设置 include_path 配置选项

    set_include_path() 函数可以在php程序中动态改变php的 include_path参数,其参数是一个字符串,多个不同的目录可以串联在一起作为一个参数一起提交--不同的目录间使用目录分割符号分开,在类unix的系统中这个分隔符是":",在windows系统中这个分隔符是";",所以php提供一个常量PATH_SEPARATOR 来表示当前系统中的这个分隔符. set_include_path - 设置 include_path 配置选项 说明 st

  • PHP图像识别技术原理与实现

    其实图像识别技术与我们平时做的密码验证之类的没有什么区别,都是事先把要校验的数据入库,然后使用时将录入(识别)的数据与库中的数据做对比,只不过图像识别技术有一部分的容错性,而我们平时的密码验证是要100%匹配. 前几天,有朋友谈到做游戏点击抽奖,识别图片中的文字,当时立马想到的就是js控制或者flash做遮罩层,感觉这种办法是最方便快捷效果好,而且节省服务器资源,但是那边提的要求竟然是通过php识别图像中的文字. 赶巧那两天的新闻有:1.马云人脸识别支付:2.12306使用新的验证码,说什么现在

  • PHP读取大文件的几种方法介绍

    读取大文件一直是一个头痛的问题,我们像使用php开发读取小文件可以直接使用各种函数实现,但一到大文章就会发现常用的方法是无法正常使用或时间太长太卡了,下面我们就一起来看看关于php读取大文件问题解决办法,希望例子能帮助到各位. 场景:PHP读取超大文件,例如1G的日志文件,我这里使用的是400M的access.log文件 1.使用file直接读取 <?php $starttime=microtime_float(); ini_set('memory_limit', '-1'); $file =

  • java读取XML文件的四种方法总结(必看篇)

    JAVA操作XML文档主要有四种方式,分别是DOM.SAX.JDOM和DOM4J,DOM和SAX是官方提供的,而JDOM和DOM4J则是引用第三方库的,其中用的最多的是DOM4J方式.运行效率和内存使用方面最优的是SAX,但是由于SAX是基于事件的方式,所以SAX无法在编写XML的过程中对已编写内容进行修改,但对于不用进行频繁修改的需求,还是应该选择使用SAX. 下面基于这四种方式来读取XML文件. 第一,以DOM的方式实现. package xmls; import org.w3c.dom.D

  • python 读取yaml文件的两种方法(在unittest中使用)

    作者:做梦的人(小姐姐) 出处:https://www.cnblogs.com/chongyou/ python读取yaml文件使用,有两种方式: 1.使用ddt读取 2,使用方法读取ddt的内容,在使用方法中进行调用 1.使用ddt读取 @ddt.ddt class loginTestPage(unittest.TestCase):     @ddt.file_data(path)     @ddt.unpack     def testlogin(self,**kwargs):       

  • Java读取Properties文件的七种方法的总结

    Java读取Properties文件的方法总结 读取.properties配置文件在实际的开发中使用的很多,总结了一下,有以下几种方法: 其实很多都是大同小异,概括起来就2种: 先构造出一个InputStream来,然后调用Properties#load() 利用ResourceBundle,这个主要在做国际化的时候用的比较多. 例如:它能根据系统语言环境自动读取下面三个properties文件中的一个: resource_en_US.properties resource_zh_CN.prop

  • asp.net读取excel文件的三种方法示例

    方法一:采用OleDB读取Excel文件 把Excel文件当做一个数据源来进行数据的读取操作,实例如下: 复制代码 代码如下: public DataSet ExcelToDS(string Path)   {   string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source="+ Path +";"+"Extended Properties=Excel 8.0;&

  • .NET读取Excel文件的三种方法的区别

    ASP.NET读取Excel文件方法一:采用OleDB读取Excel文件: 把Excel文件当做一个数据源来进行数据的读取操作,实例如下: 复制代码 代码如下: public DataSet ExcelToDS(string Path)   {    string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source="+ Path +";"+"Extended Prop

  • PHP读取大文件的类SplFileObject使用介绍

    如果加载的文件特别大时,如几百M,上G时,这时性能就降下来了,那么PHP里有没有对大文件的处理函数或者类呢? 答案是:有的.PHP真的越来越"面向对象"了,一些原有的基础的SPL方法都开始陆续地实现出class了.从 PHP 5.1.0 开始,SPL 库增加了 SplFileObject 与 SplFileInfo 两个标准的文件操作类.SplFileInfo 是从 PHP 5.1.2 开始实现的.从字面意思理解看,可以看出 SplFileObject 要比 SplFileInfo 更

  • JAVA读取属性文件的几种方法总结

    1.使用java.util.Properties类的load()方法 示例: Java代码InputStream in = lnew BufferedInputStream(new FileInputStream(name));     Properties p = new Properties();     p.load(in); 2.使用java.util.ResourceBundle类的getBundle()方法  示例: Java代码ResourceBundle rb = Resourc

  • java读取excel文件的两种方法

    本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 方式一: 借用 package com.ij34.util; /** * @author Admin * @date 创建时间:2017年8月29日 下午2:07:59 * @version 1.0 *@type_name myclass */ import java.io.File; import java.io.IOException; import jxl.Cell; import jxl.Sheet;

  • Javascript动态引用CSS文件的2种方法介绍

    最近做一个项目,需要javascript动态插入样式,结果以前的方法失效了!查了2个小时的原因竟然是自己手贱,这个最后再说! javascript插入样式在前端开发中应用比较广泛,特别是在修改前端表现和页面换肤的时候.最近做的这个任务是用户在别人的站点上点击一个按钮,就会在别的站点页面下插入一个脚本,执行,这其中包含了样式的插入. 一般情况下javascript动态插入样式有两种,一种页面中引入外部样式,在<head>中使用<link>标签引入一个外部样式文件,另一种是在页面中使用

随机推荐