`
webcode
  • 浏览: 6079693 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

PHP对大文件的处理思路

 
阅读更多

需求: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容。

在php中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。

1. 直接采用file函数来操作
由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的memory_limit = 16M来进行设置,这个值如果设置-1,则内存使用量不受限制。

下面是一段用file来取出这具文件最后一行的代码。代码执行大概2分钟左右。

view sourceprint?
01 $fp = fopen($file, "r");

02 $num = 10;

03 $chunk = 4096;

04 $fs = sprintf("%u", filesize($file));

05 $max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);

06 for ($len = 0; $len < $max; $len += $chunk) {

07 $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;

08 fseek($fp, ($len + $seekSize) * -1, SEEK_END);

09 $readData = fread($fp, $seekSize) . $readData;

10

11 if (substr_count($readData, "\n") >= $num + 1) {

12 preg_match("!(.*?\n){".($num)."}$!", $readData, $match);

13 $data = $match[0];

14 break;

15 }

16 }

17 fclose($fp);

18 echo $data;
我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了。

2.直接调用linux的tail命令来显示最后几行
在linux命令行下,可以直接使用tail -n 10 access.log很轻易的显示日志文件最后几行,可以直接用php来调用tail命令,执行php代码如下.整个代码执行完成耗时 0.0034 (s)

view sourceprint?
1 file = 'access.log';

2 $file = escapeshellarg($file); // 对命令行参数进行安全转义

3 $line = `tail -n 1 $file`;

4 echo $line;
3. 直接使用php的fseek来进行文件操作
这种方式是最为普遍的方式,它不需要将文件的内容全部读入内存,而是直接通过指针来操作,所以效率是相当高效的.在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法.

方法一:

首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置,再取这一行的位置,依次类推,直到找到了$num行。

view sourceprint?
01 function tail($fp,$n,$base=5)

02 {

03 assert($n>0);

04 $pos = $n+1;

05 $lines = array();

06 while(count($lines)< =$n){

07 try{

08 fseek($fp,-$pos,SEEK_END);

09 } catch (Exception $e){

10 fseek(0);

11 break;

12 }

13 $pos *= $base;

14 while(!feof($fp)){

15 array_unshift($lines,fgets($fp));

16 }

17 }

18 return array_slice($lines,0,$n);

19 }

20 var_dump(tail(fopen("access.log","r+"),10));
方法二:

还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换行符(\n)的个数来判断是否已经读完最后$num行数据.

view sourceprint?
01 $fp = fopen($file, "r");

02 $line = 10;

03 $pos = -2;

04 $t = " ";

05 $data = "";

06 while ($line > 0) {

07 while ($t != "\n") {

08 fseek($fp, $pos, SEEK_END);

09 $t = fgetc($fp);

10 $pos --;

11 }

12 $t = " ";

13 $data .= fgets($fp);

14 $line --;

15 }

16 fclose ($fp);

17 echo $data
方法三:

view sourceprint?
1 ini_set('memory_limit','-1');

2 $file = 'access.log';

3 $data = file($file);

4 $line = $data[count($data)-1];

5 echo $line;

分享到:
评论

相关推荐

    解决PHP搭建大文件如何上传(图文)

    默认情况下,PHP对上传文件的大小有限制,通常为2MB,这可能导致用户在尝试上传超过这个限制的大文件时遇到错误。要解决这个问题,我们需要调整PHP配置文件`php.ini`中的几个关键设置: 1. `upload_max_filesize`:...

    用PHP文件上传的具体思路及实现

    表单的`enctype`属性应设置为`multipart/form-data`...总的来说,实现PHP文件上传需要考虑用户体验、文件安全性和服务器资源管理等多个方面。通过合理的代码设计和严谨的验证机制,可以构建出安全可靠的文件上传功能。

    php 大文件分块上传源码,thinkphp,larvavel

    在PHP环境中,由于默认的文件上传限制,处理大文件可能会遇到挑战。标题提到的"php 大文件分块上传源码,thinkphp,laravel"涉及到的技术点是通过分块(Chunked)上传策略来解决这个问题,适用于ThinkPHP和Laravel这...

    PHP时尚编程百例 提供基础、思路、步骤等

    这些实例可能包括但不限于数据库操作(如MySQL连接、查询、更新等)、Web表单处理、文件操作、会话管理、模板引擎、类库和框架的使用、API接口的调用等。通过实际操作这些例子,学习者可以更好地理解和掌握PHP的实战...

    单文件管理器Files 是一个单文件 PHP 应用程序

    总结起来,"单文件管理器Files"是一个高效且实用的工具,它通过单一的PHP文件实现了丰富的文件管理功能,包括多种文件类型的预览和编辑,以及基本的文件操作。对于那些需要简单易用、易于部署的文件管理解决方案的...

    php文件上传后端处理小技巧_.docx

    通过对不同业务场景下的PHP文件上传后端处理技巧的介绍,可以看出,根据具体需求采用合适的策略可以有效提高系统性能和用户体验。同时,确保上传过程的安全性同样重要,开发者在设计上传功能时应充分考虑到这一点。...

    PHP+Flash文件上传程序(含flash fla源码)

    虽然现在Flash已经逐渐被淘汰,但其原理和思路对于理解现代Web开发中的文件上传处理仍然有价值。对于学习者来说,研究这个程序可以深化对PHP后端处理和Flash前端交互的理解,为今后使用JavaScript、HTML5等现代技术...

    php快速删除目录及目录中的文件

    在PHP编程中,有时我们需要处理文件系统操作,例如删除目录及其内部的所有文件。"php快速删除目录及目录中的文件"这个话题就是关于如何高效地执行此类任务。在FTP(File Transfer Protocol)中,删除文件或目录可能...

    PHP写的文件压缩类

    5. **文件流处理**:为了处理大文件或提高性能,类库可能支持文件流,即不一次性加载整个文件到内存,而是按块读取和写入。 6. **错误处理**:为了确保稳健性,类库应包括适当的错误处理机制,如检查文件是否存在、...

    导出路径文件,导出指定文件夹,批量复制文件,文件夹导出带路径工具

    这样的过程可以极大地节省手动操作的时间,尤其当处理的文件数量庞大时。 自动添加导出时间的功能使得每次导出都有时间戳作为标识,这对于跟踪和管理历史版本非常有帮助。这可能是通过在PHP中使用`date()`函数来...

    php漏洞探测思路

    - 即使不知道源码细节,也可以通过了解Zend Engine如何处理PHP文件来发现潜在的安全问题。 - 例如,通过观察和分析被Zend Engine编译和执行的文件,可以推断出可能存在哪些类型的漏洞。 2. **利用预定义函数:** ...

    PHP实例开发源码-八年 php文件管理器.zip

    此外,文件管理器还可能涉及文件的排序、过滤等操作,这通常需要对文件信息进行处理,如根据时间戳、大小等属性进行排序。 权限管理是保证系统安全的关键。在PHP中,我们可以使用`chmod()`函数改变文件或目录的权限...

    PHP文件上传之多文件上传的实现思路

    // 引入上传文件处理函数 $path = './uploads/'; // 设置文件保存路径 foreach ($file as $v) { $info = uploadFile($v, $path); // 调用上传函数 // 判断上传状态并输出结果 if ($info['isok']) { echo '...

    PHP实例开发源码-孤雨在线php文件管理系统.zip

    在孤雨在线PHP文件管理系统中,PHP被用来处理用户的请求,生成动态页面,以及与服务器端的文件系统进行交互。 该系统的实现涉及到多个PHP核心概念和技术: 1. **HTTP协议**:PHP通过接收HTTP请求来获取用户操作...

    基于PHP的地震媒体文件管理系统的研究.pdf

    三是媒体文件的自动分类和标记,开发基于机器学习和自然语言处理技术的媒体文件自动分类和标记系统。 结论 本文的研究结果表明,基于PHP的地震媒体文件管理系统可以满足媒体文件管理的标准化和信息化需求。该系统...

    PHP文件上传处理案例分析

    ### PHP文件上传处理方法 PHP处理文件上传的主要方法是使用全局数组$_FILES,该数组包含了通过POST方法上传的所有文件的相关信息。PHP将上传的文件首先存储在临时目录中,然后通过move_uploaded_file()函数移动到...

    php获取目录下所有文件及目录(多种方法)(推荐)

    这些方法对于处理文件系统操作提供了基本的框架和思路。在实际开发中,我们可能需要根据具体的需求对这些方法进行改进和扩展,比如实现文件过滤、排除隐藏文件等。此外,由于涉及到文件和目录的操作,安全问题也不容...

    PHP大文件分割上传 PHP分片上传

    文件中的几个关键配置项对处理大文件上传至关重要: 1. upload_max_filesize:这个指令设置PHP能够上传的最大文件大小。 2. post_max_size:此指令决定了PHP能够接收的最大POST请求的数据大小。 3. memory_limit:...

    PHP读取txt文本文件并分页显示的方法_.docx

    描述中提到的“涉及php操作文件的技巧”指的是通过PHP的文件处理函数来读取和处理文件内容。在这个例子中,主要是使用`file_get_contents()`函数获取TXT文件的全部内容,然后通过字符串处理函数来实现分页。 在提供...

    一个PHP模板,主要想体现一下思路

    首先,模板引擎的工作方式通常是将HTML文件转换为PHP文件。在这个例子中,开发者通过`require('template.php')`引入模板处理类,然后创建一个`Template`对象,如`$tpl = new Template($tpl_prefix)`。这里的`$tpl_...

Global site tag (gtag.js) - Google Analytics