How to read only 5 last line of the text file in PHP?

前端 未结 18 1591
陌清茗
陌清茗 2020-11-28 08:45

I have a file named file.txt which is update by adding lines to it.

I am reading it by this code:

$fp = fopen(\"file.txt\", \"r\");
$da         


        
相关标签:
18条回答
  • 2020-11-28 09:08

    Untested code, but should work:

    $file = file("filename.txt");
    for ($i = max(0, count($file)-6); $i < count($file); $i++) {
      echo $file[$i] . "\n";
    }
    

    Calling max will handle the file being less than 6 lines.

    0 讨论(0)
  • 2020-11-28 09:08

    This doesn't use file() so it will be more efficient for huge files;

    <?php
    function read_backward_line($filename, $lines, $revers = false)
    {
        $offset = -1;
        $c = '';
        $read = '';
        $i = 0;
        $fp = @fopen($filename, "r");
        while( $lines && fseek($fp, $offset, SEEK_END) >= 0 ) {
            $c = fgetc($fp);
            if($c == "\n" || $c == "\r"){
                $lines--;
                if( $revers ){
                    $read[$i] = strrev($read[$i]);
                    $i++;
                }
            }
            if( $revers ) $read[$i] .= $c;
            else $read .= $c;
            $offset--;
        }
        fclose ($fp);
        if( $revers ){
            if($read[$i] == "\n" || $read[$i] == "\r")
                array_pop($read);
            else $read[$i] = strrev($read[$i]);
            return implode('',$read);
        }
        return strrev(rtrim($read,"\n\r"));
    }
    //if $revers=false function return->
    //line 1000: i am line of 1000
    //line 1001: and i am line of 1001
    //line 1002: and i am last line
    //but if $revers=true function return->
    //line 1002: and i am last line
    //line 1001: and i am line of 1001
    //line 1000: i am line of 1000
    ?>
    
    0 讨论(0)
  • 2020-11-28 09:08

    I've tested this one. It works for me.

    function getlast($filename,$linenum_to_read,$linelength){
    
       // this function takes 3 arguments;
    
    
       if (!$linelength){ $linelength = 600;}
    $f = fopen($filename, 'r');
    $linenum = filesize($filename)/$linelength;
    
        for ($i=1; $i<=($linenum-$linenum_to_read);$i++) {
        $data = fread($f,$linelength);
        }
    echo "<pre>";       
        for ($j=1; $j<=$linenum_to_read+1;$j++) {
        echo fread($f,$linelength);
        }
    
    echo "</pre><hr />The filesize is:".filesize("$filename");
    }
    
    getlast("file.txt",6,230);
    
    
    ?>
    
    0 讨论(0)
  • 2020-11-28 09:10

    FAST

    Here is FAST method for LARGE files with LOW memory cost - I develop Wallace Maxters answer (if you want to upvote - do it on his answer) by wrap his code inside handy function and add reverse feature

    function readLastLines($filename, $num, $reverse = false)
    {
        $file = new \SplFileObject($filename, 'r');
        $file->seek(PHP_INT_MAX);
        $last_line = $file->key();
        $lines = new \LimitIterator($file, $last_line - $num, $last_line);
        $arr = iterator_to_array($lines);
        if($reverse) $arr = array_reverse($arr);
        return implode('',$arr);
    }
    
    // use it by
    $lines = readLastLines("file.txt", 5) // return string with 5 last lines
    
    0 讨论(0)
  • 2020-11-28 09:13

    this is read last 10 line from text file

    $data = array_slice(file('logs.txt'),10);
    
        foreach ($data as $line) 
    
        {
    
            echo $line."<br/>";
        }
    
    0 讨论(0)
  • 2020-11-28 09:14

    For a large file, reading all the lines into an array with file() is a bit wasteful. Here's how you could read the file and maintain a buffer of the last 5 lines:

    $lines=array();
    $fp = fopen("file.txt", "r");
    while(!feof($fp))
    {
       $line = fgets($fp, 4096);
       array_push($lines, $line);
       if (count($lines)>5)
           array_shift($lines);
    }
    fclose($fp);
    

    You could optimize this a bit more with some heuristics about likely line length by seeking to a position, say, approx 10 lines from the end, and going further back if that doesn't yield 5 lines. Here's a simple implementation which demonstrates that:

    //how many lines?
    $linecount=5;
    
    //what's a typical line length?
    $length=40;
    
    //which file?
    $file="test.txt";
    
    //we double the offset factor on each iteration
    //if our first guess at the file offset doesn't
    //yield $linecount lines
    $offset_factor=1;
    
    
    $bytes=filesize($file);
    
    $fp = fopen($file, "r") or die("Can't open $file");
    
    
    $complete=false;
    while (!$complete)
    {
        //seek to a position close to end of file
        $offset = $linecount * $length * $offset_factor;
        fseek($fp, -$offset, SEEK_END);
    
    
        //we might seek mid-line, so read partial line
        //if our offset means we're reading the whole file, 
        //we don't skip...
        if ($offset<$bytes)
            fgets($fp);
    
        //read all following lines, store last x
        $lines=array();
        while(!feof($fp))
        {
            $line = fgets($fp);
            array_push($lines, $line);
            if (count($lines)>$linecount)
            {
                array_shift($lines);
                $complete=true;
            }
        }
    
        //if we read the whole file, we're done, even if we
        //don't have enough lines
        if ($offset>=$bytes)
            $complete=true;
        else
            $offset_factor*=2; //otherwise let's seek even further back
    
    }
    fclose($fp);
    
    var_dump($lines);
    
    0 讨论(0)
提交回复
热议问题