Read last line from file

2020-01-28 05: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 need to read the last line from that file.

The problem is this action will be called via an AJAX request pretty often and when the file size of that log gets over 5-6MB it's rather not good for the server. So I'm thinking I have to read the last line but not to read the whole file and pass through it or load it in RAM because that would just load to death my box.

Is there any optimization for this operation so that it run smooth and not harm the server or kill Apache?

Other option that I have is to exec('tail -n 1 /path/to/log') but it doesn't sound so good.

Later edit: I DO NOT want to put the file in RAM because it might get huge. fopen() is not an option.

标签: php file file-io
12条回答
萌系小妹纸
2楼-- · 2020-01-28 05:26

I would use file() that reads the file into an array, reverse the array and get the first element or pop the array:

$last_line = array_pop(file($filename));

If you want performance try opening the file and using the file pointer to navigate into it.

查看更多
\"骚年 ilove
3楼-- · 2020-01-28 05:33
function readlastline() 
{ 
       $fp = @fopen("/dosmnt/LOGFILE.DAT", "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; 
} 

Source: http://forums.devshed.com/php-development-5/php-quick-way-to-read-last-line-156010.html

查看更多
4楼-- · 2020-01-28 05:36

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`;
查看更多
来,给爷笑一个
5楼-- · 2020-01-28 05:37

You're looking for the fseek function. There are working examples of how to read the last line of a file in the comments section there.

查看更多
【Aperson】
6楼-- · 2020-01-28 05: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.

查看更多
我命由我不由天
7楼-- · 2020-01-28 05:38

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
                )
        );
查看更多
登录 后发表回答