Read file lines backwards (fgets) with php

前端 未结 4 1890
轮回少年
轮回少年 2021-01-17 18:03

I have a txt file that I want to read backwards, currently I\'m using this:

$fh = fopen(\'myfile.txt\',\'r\');
while ($line = fgets($fh)) {
  echo $line.\"         


        
相关标签:
4条回答
  • 2021-01-17 18:48

    Try something simpler like this..

    print_r(array_reverse(file('myfile.txt')));
    
    0 讨论(0)
  • 2021-01-17 18:50

    First way:

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

    Second Way (a):

    To completely reverse a file:

    $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);
    
    

    Second Way (b): Of course, you wanted line-by-line reversal...

    
    $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") {
            // analyse completed line $output[$ln] if need be
            $ln++;
            continue;
            }
        $output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : '');
        }
    fclose($fl);
    print_r($output);
    
    
    0 讨论(0)
  • 2021-01-17 18:51

    Here is my solution for just printing the file backwards. It is quite memory-friendly. And seems more readable (IMO [=in my opinion]).

    It goes through the file backwards, count the characters till start of a line or start of the file and then reads and prints that amount of characters as a line, then moves cursor back and reads another line like that...

      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
      }
    

    Of course replace PATH_TO_YOUR_FILE with your own path to your file, @ is used when opening the file, because when the file is not found or can't be opened - warning is raised - if you want to display this warning - just remove the error surpressor '@'.

    0 讨论(0)
  • 2021-01-17 18:51

    If the file is not so big you can use file():

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

    However, this requires the whole file to be in memory, that's why it is not suited for really large files.

    0 讨论(0)
提交回复
热议问题