使用php反向读取文件(fgets)的每一行

10

我有一个txt文件,想要倒序读取,目前我正在使用这个方法:

$fh = fopen('myfile.txt','r');
while ($line = fgets($fh)) {
  echo $line."<br />";
}

这会输出我的文件中的所有行。
我想要从底部向上读取这些行。

有没有方法可以做到这一点?

5个回答

16

第一种方法:

$file = file("test.txt");
$file = array_reverse($file);
foreach($file as $f){
    echo $f."<br />";
}

第二种方法(a):

完全反转文件:

$fl = fopen("\some_file.txt", "r");
for($x_pos = 0, $output = ''; fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
    $output .= fgetc($fl);
    }
fclose($fl);
print_r($output);

第二种方法(b):当然,您希望按行反转......

$fl = fopen("\some_file.txt", "r");
for($x_pos = 0, $ln = 0, $output = array(); fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
    $char = fgetc($fl);
    if ($char === "\n") {
        // 如果需要,请分析完成的行 $output[$ln]
        $ln++;
        continue;
        }
    $output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : '');
    }
fclose($fl);
print_r($output);


模式'a+'会自动将光标移动到文件末尾 :) (但是有一个bug,即光标在第一次I/O之后才会移动,而不是立即移动) - jave.web

4
这是我提供的只逆序打印文件的解决方案。它相当< strong>节省内存。并且看起来更易读(在我看来)。它反向通过文件,计算字符,直到行或文件的开头,然后读取和打印该字符数作为一行,然后将光标移回并像那样读取另一行...
  if( $v = @fopen("PATH_TO_YOUR_FILE", 'r') ){ //open the file
    fseek($v, 0, SEEK_END); //move cursor to the end of the file
    /* help functions: */
    //moves cursor one step back if can - returns true, if can't - returns false
    function moveOneStepBack( &$f ){ 
      if( ftell($f) > 0 ){ fseek($f, -1, SEEK_CUR); return true; }
        else return false;
    }
    //reads $length chars but moves cursor back where it was before reading 
    function readNotSeek( &$f, $length ){ 
      $r = fread($f, $length);
      fseek($f, -$length, SEEK_CUR);
      return $r;  
    }

    /* THE READING+PRINTING ITSELF: */
    while( ftell($v) > 0 ){ //while there is at least 1 character to read
      $newLine = false;
      $charCounter = 0;

      //line counting
      while( !$newLine && moveOneStepBack( $v ) ){ //not start of a line / the file
        if( readNotSeek($v, 1) == "\n" ) $newLine = true;
        $charCounter++;              
      } 

      //line reading / printing
      if( $charCounter>1 ){ //if there was anything on the line
        if( !$newLine ) echo "\n"; //prints missing "\n" before last *printed* line            
        echo readNotSeek( $v, $charCounter ); //prints current line  
      }   

    }
    fclose( $v ); //close the file, because we are well-behaved
  }

当然,将PATH_TO_YOUR_FILE替换为您自己的文件路径,使用@打开文件时,因为当找不到文件或无法打开文件时会发出警告-如果要显示此警告-只需删除错误抑制器'@'。

谢谢。我认为这是最好的解决方案。 - Luvias
附注:这对于每行合理数量的字符来说是内存友好的 :) - jave.web

4
尝试类似这样更简单的方法...
print_r(array_reverse(file('myfile.txt')));

2

如果文件不是很大,您可以使用file()函数:

$lines = file($file);
for($i = count($lines) -1; $i >= 0; $i--){
    echo $lines[$i] . '<br/>';
}

然而,这需要将整个文件加载到内存中,因此它不适用于非常大的文件。


0

这是我的简单解决方案,不会弄乱任何东西或添加更复杂的代码

$fh = fopen('myfile.txt','r');
while ($line = fgets($fh)) {
  $result = $line . "<br>" . $result;
}
echo $result // or return $result if you are using it as a function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接