Read last line from file

后端 未结 12 1675
南方客
南方客 2020-12-01 09:13

I\'ve been bumping into a problem. I have a log on a Linux box in which is written the output from several running processes. This file can get really big sometimes and I ne

相关标签:
12条回答
  • 2020-12-01 09:37

    Would it be possible to optimize this from the other side? If so, just let the logging application always log the line to a file while truncating it (i.e. > instead of >>)

    Some optimization might be achieved by "guessing" though, just open the file and with the average log line width you could guess where the last line would be. Jump to that position with fseek and find the last line.

    0 讨论(0)
  • 2020-12-01 09:39

    Here is a compilation of the answers here wrapped into a function which can specify how many lines should be returned.

    function getLastLines($path, $totalLines) {
      $lines = array();
    
      $fp = fopen($path, 'r');
      fseek($fp, -1, SEEK_END);
      $pos = ftell($fp);
      $lastLine = "";
    
      // Loop backword until we have our lines or we reach the start
      while($pos > 0 && count($lines) < $totalLines) {
    
        $C = fgetc($fp);
        if($C == "\n") {
          // skip empty lines
          if(trim($lastLine) != "") {
            $lines[] = $lastLine;
          }
          $lastLine = '';
        } else {
          $lastLine = $C.$lastLine;
        }
        fseek($fp, $pos--);
      }
    
      $lines = array_reverse($lines);
    
      return $lines;
    }
    
    0 讨论(0)
  • 2020-12-01 09:41

    This is my solution with only one loop

            $line = '';
            $f = fopen($file_path, 'r');
            $cursor = 0 ;
            do  {
                fseek($f, $cursor--, SEEK_END);
                $char = fgetc($f);
                $line = $char.$line;
            } while (
                    $cursor > -1 || (
                     ord($char) !== 10 &&
                     ord($char) !== 13
                    )
            );
    
    0 讨论(0)
  • 2020-12-01 09:44

    Your problem looks similar to this one

    The best approach to avoid loading the whole file into memory seems to be:

    $file = escapeshellarg($file); // for the security concious (should be everyone!)
    $line = `tail -n 1 $file`;
    
    0 讨论(0)
  • 2020-12-01 09:45

    Untested code from the comments of http://php.net/manual/en/function.fseek.php

    jim at lfchosting dot com 05-Nov-2003 02:03
    Here is a function that returns the last line of a file.  This should be quicker than reading the whole file till you get to the last line.  If you want to speed it up a bit, you can set the $pos = some number that is just greater than the line length.  The files I was dealing with were various lengths, so this worked for me. 
    
    <?php 
    function readlastline($file) 
    { 
            $fp = @fopen($file, "r"); 
            $pos = -1; 
            $t = " "; 
            while ($t != "\n") { 
                  fseek($fp, $pos, SEEK_END); 
                  $t = fgetc($fp); 
                  $pos = $pos - 1; 
            } 
            $t = fgets($fp); 
            fclose($fp); 
            return $t; 
    } 
    ?>
    0 讨论(0)
  • 2020-12-01 09:50

    Use fseek. You seek to the last position and seek it backward (use ftell to tell the current position) until you find a "\n".

    
    $fp = fopen(".....");
    fseek($fp, -1, SEEK_END); 
    $pos = ftell($fp);
    $LastLine = "";
    // Loop backword util "\n" is found.
    while((($C = fgetc($fp)) != "\n") && ($pos > 0)) {
        $LastLine = $C.$LastLine;
        fseek($fp, $pos--);
    }
    

    NOTE: I've not tested. You may need some adjustment.

    UPDATE: Thanks Syntax Error for pointing out about empty file.

    :-D

    UPDATE2: Fixxed another Syntax Error, missing semicolon at $LastLine = ""

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