如何在不读取全部文件内容的前提下倒序取出文件的最后几条数据?Demo:
Filename:menu.txt
Content:
aaaaaaaa
bbbbbbbb
cccccccc
dddddddd
eeeeeeeeResult:(取出最后3条)
$res = array(
  array("eeeeeeee"),
  array("dddddddd"),
  array("cccccccc"),
);

解决方案 »

  1.   

    将文件的指针移动到你要开始读取的位置(利用fseek()函数),然后读取文件。
      

  2.   

    $filename = "menu.txt";//文件名
    $handle = fopen( $filename, "rb" );
    if( fseek( $handle, 0, SEEK_END ) !== -1 ){//指向文件尾
    $k = 3;//获取的条数
    $s = 0;
    while( $k-- ){
    if ( fseek( $handle, $s-1, SEEK_END ) === -1 ) break;//指针向前移动一个位置
    while( fgetc($handle)!="\n" ){
    --$s;
    fseek( $handle, $s, SEEK_END );
    }
    fseek( $handle, $s+1, SEEK_END );//指针后移一位
    echo fgets($handle) . "<br/>";
    }
    }else{
    echo 'no';
    }
    楼主可以看看  
      

  3.   

    本帖最后由 xuzuning 于 2012-11-21 12:46:50 编辑
      

  4.   


    1、如何是在第一次读取后,文件又加了内容,第二次读取更新的内容?
    Demo2:
    filename:menu.txt
    content:
    aaaaaaaa
    bbbbbbbb
    cccccccc
    dddddddd
    eeeeeeee
    ffffffff
    ggggggggresult:
    array(
      array("gggggggg"),
      array("ffffffff")
    );
    2、如何从指定行倒序读取指定行数?
    Demo3:
    filename:menu.txt
    content:
    aaaaaaaa
    bbbbbbbb
    cccccccc
    dddddddd
    eeeeeeee
    ffffffff
    ggggggggresult: (从倒数第2行,读取3行数据)
    array(
      array("ffffffff"),
      array("eeeeeeee"),
      array("dddddddd")
    );
      

  5.   

    1、如何是在第一次读取后,文件又加了内容,第二次读取更新的内容?
    保存上次读取时的文件大小 $size
    fseek($fp, $size);
    然后用 fgets 正序读取,array_unshift 逆序保存2、如何从指定行倒序读取指定行数?
    从倒数第2行,读取3行数据
    简单的逻辑判断,倒序读取5行,不保存前2行
      

  6.   

    在windows下的文件中貌似没有\d,不走switch中的case "\d"。
    貌似是“\r\n”,但如何执行这段代码?
    if($t) {
            array_unshift($res, $t);//保存缓冲区
            $n--;
          }
          $t = '';
      

  7.   

    case 是顺序执行的,所以要有 break 跳出
      

  8.   


    #我将#4楼的带面封装了下,总是返回空数组,为题在于$t开始就是空的,没有其他赋值的地方function invertedReadFile($filename,$n=20){
    $fp = fopen($filename, 'r');//打开文件
    if (!$fp) return false;
    fseek($fp, -1, SEEK_END);//跳到最后一个字节出
    $res = array();//初始化结果数组
    $t = '';//初始化缓冲区
    while($n && $ch = fgetc($fp)) {//循环读取
      switch($ch) {
        case "\n":
        case "\r\n" || "\r"://是行尾
    #echo "-->>4<br>";
          if($t) {  #这里是否是判断$n为真?
            array_unshift($res, $t);//保存缓冲区
            echo "res-->>";print_r($res);echo "<br>";
            $n--;
          }
          $t = '';
          break;
        default:
    #echo "-->>5<br>";
          $t = $ch . $t;//缓存字符  #这里的$t和最终结果有什么关系?
      }
      fseek($fp, -2, SEEK_CUR);//向前跳2的字符
    }
    return $res;
    }
      

  9.   

    print_r(invertedReadFile('menu.txt', 3));function invertedReadFile($filename,$n=20){
        $fp = fopen($filename, 'r');//打开文件
        if (!$fp) return false;
        fseek($fp, -1, SEEK_END);//跳到最后一个字节出
        $res = array();//初始化结果数组
        $t = '';//初始化缓冲区
        while($n && $ch = fgetc($fp)) {//循环读取
          switch($ch) {
            case "\n":
            case "\r"://是行尾
              if($t) {  #这里是否是判断$n为真?
                array_unshift($res, $t);//保存缓冲区
                $n--;
              }
              $t = '';
              break;
            default:
              $t = $ch . $t;//缓存字符  #这里的$t和最终结果有什么关系?
          }
          fseek($fp, -2, SEEK_CUR);//向前跳2的字符
        }
        return $res;
    }Array
    (
        [0] => cccccccc
        [1] => dddddddd
        [2] => eeeeeeee
    )case "\r\n" || "\r"://是行尾
    这样写是错误的!语法错,不知为什么php不报错
    先不说 fgetc 一次返回一个字符,不会出现 "\r\n" 字符组合
    switch($ch) {
      case "\n":
      case "\r":

    switch($ch) {
      case $ch == "\n" || $ch == "\r": //多条件要这样写
    是等价的表示换行
    window 用 "\r\n"
    linux 用 "\n"
    mac 用 "\r"
    代码中都涵盖了if($t) 的作用是防止在window中重复执行保存操作
      

  10.   


    #很是奇怪的问题,我用#3的方法获得了结果
    function aaa($filename, $k=20){
    $handle = fopen( $filename, "rb" );
    if( fseek( $handle, 0, SEEK_END ) !== -1 ){//指向文件尾
        $s = 0;
        $res = array();
        while( $k-- ){
            if ( fseek( $handle, $s-1, SEEK_END ) === -1 ) break;//指针向前移动一个位置
            while( fgetc($handle)!="\n" ){
                --$s;
                fseek( $handle, $s, SEEK_END );
            }
            fseek( $handle, $s+1, SEEK_END );//指针后移一位
            $res[] = fgets($handle);
        }
        return $res;
    }else{
        return false;
    }
    }#但是#12的方法运行后一直是返回空数组:Array();
    就是if($t){}没进来。
    $t=''; 之后没有赋值,一直为null
    所以if($t)不成立。