PHP读取大文件(100M-1G以上)的写法 收藏
2009年11月29日


面试时经常会有这种问题,给你一个100M或1G的文本文件,如何读取?说实在的,很少人测过!
我也没做过,只是说分段取!在新浪面试时一考官问我:如何取?接着又一个问题?fopen打一个1G的文件有问题吗?能不能打开?

偶实话实话,不知道!真的不知道,手册上说fopen打开一个流,但打开要不要加载内存?真的不知道?这个问题?还是留着以后解决吧!

下面是整理的一点资料,以备后查:

例如我有一个文件xxxxx.dat(1G大小)

这个文件里的数据格式是:



111111111111111111111111111111111111111111."\r\n"


222222222222222222222222222222222222222222."\r\n"
......


aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."\r\n"


bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb."\r\n"
......


zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz."\r\n"

如果我要从



zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz往上读取20条记录,该怎么读取?


下面是CSDN上几位朋友的代码:


system128的代码:


  1.  
  2. <?php
  3. $filename = "c:/logfile.log"; //  需要读取的文件
  4. $sep = "

    "; // 行分隔符

  5. $count = 5; // 读取行数
  6.  
  7.  
  8. $handle = fopen($filename,"a+");
  9. $len= strlen($sep);
  10. $pos = -$len;
  11. $i = 0;
  12. $content = ''; // 最终内容
  13. $cContent = '';// 当前读取内容寄存
  14. do{
  15.     fseek($handle,$pos,SEEK_END);
  16.     $cContent = fread($handle,$len);
  17.     $content = $cContent.$content;
  18.     $pos -= $len;
  19.     if ($sep === $cContent ){
  20.         $i++;
  21.     }
  22. }while($i<$count);
  23. echo $content;
  24. ?>
  25.  
  26.  

syu
(神无月)的代码:
  1. <?php
  2. $fp = fopen('test.txt','r');
  3. $fs = filesize('test.txt');
  4. $i = $n = NULL;
  5. while($i <4)
  6. {
  7. fseek($fp,$fs--);
  8. $n = fread($fp,1);
  9. ($n=="

    ")?$i++:1;

  10. echo $n;
  11. }
  12. fclose($fp);
  13.  


system128:
  1. <?php
  2. function getLatestLines($filename,$count = 20,$sep = "

    "){ //  注意这里必须用双引号

  3.     $content = ''; // 最终内容
  4.     $_current = '';// 当前读取内容寄存
  5.     $seper = '';// 分隔符判断
  6.     $seperLen = strlen($sep); // 分隔符长度
  7.     $step= 1; // 每次走多少字符
  8.     $pos = 0;// 起始位置 -1 就是从最后一个开始
  9.     $i = 0;
  10.     $count--;
  11.     $handle = fopen($filename,'a+'); //读写模式,指针会被放在最后  当然也可以探测出 filesize然后从最后往前读。
  12.     while($i < $count && fseek($handle,$pos,SEEK_END) ===0){
  13.         // SEEK_END - 设定位置为文件尾加上 offset 。(要移动到文件尾之前的位置,需要给 offset 传递一个负值。)
  14.         $_current = fread($handle,$step);
  15.         $seper = $_current.$seper;
  16.         if (strlen($seper)>$seperLen){
  17.             $seper = substr($seper, 0, -$seperLen); // 截取当前字符最后几位。与分隔符匹配,所以长度和分隔符要一样。
  18.         }
  19.         $content = $_current.$content;
  20.         $pos -= $step; // 向后退
  21.         if ($sep === $seper ){ // 判断是否是换行或其他分隔符
  22.             $i++;
  23.         }
  24.     }
  25.     fclose($handle);
  26.     return $content;
  27. }
  28.  
  29.  
  30. $filename = 'c:/logfile.log'; //  需要读取的文件  3.5G 文件已测试过。
  31. $sep = "

    "; // 行分隔符 注意这里必须用双引号-_-#

  32. $count = 20; // 读取行数

    读取3行以下有点问题

  33. echo getLatestLines($filename,$count,$sep);
  34. ?>
  35.  
  36.  

helloyou0:
如果可以用system:
system("tail -n 20 test.txt");



http://topic.csdn.net/u/20090117/16/dd48508c-3c72-4c32-80e1-16a9eb041f25.html





 

本文永久链接: http://www.zzxj.net/blog/fxs_2008/archive/2009/11/29/99.html

发表于 @ 2009年11月29日 |评论(loading... )|收藏

发表评论 姓  名: