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.
var lastLine = File. ReadLines("file. txt"). Last();
Find out the last line of a file: Using sed (stream editor): sed -n '$p' fileName. Using tail: tail -1 fileName. using awk: awk 'END { print }' fileName.
To display the last part of the file, we use the tail command in the Linux system. The tail command is used to display the end of a text file or piped data in the Linux operating system. By default, it displays the last 10 lines of its input to the standard output. It is also complementary of the head command.
This should work:
$line = ''; $f = fopen('data.txt', 'r'); $cursor = -1; fseek($f, $cursor, SEEK_END); $char = fgetc($f); /** * Trim trailing newline chars of the file */ while ($char === "\n" || $char === "\r") { fseek($f, $cursor--, SEEK_END); $char = fgetc($f); } /** * Read until the start of file or first newline char */ while ($char !== false && $char !== "\n" && $char !== "\r") { /** * Prepend the new char */ $line = $char . $line; fseek($f, $cursor--, SEEK_END); $char = fgetc($f); } fclose($f); echo $line;
Note that this solution will repeat the last character of the line unless your file ends in a newline. If your file does not end in a newline, you can change both instances of $cursor--
to --$cursor
.
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--); } fclose($fp);
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 = ""
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With