PHP read last few lines of the file without copying the entire file to memory
W开发者_如何学运维ell you know I can use this:
<?php
$myfile = 'myfile.txt';
$command = "tac $myfile > /tmp/myfilereversed.txt";
exec($command);
$currentRow = 0;
$numRows = 20; // stops after this number of rows
$handle = fopen("/tmp/myfilereversed.txt", "r");
while (!feof($handle) && $currentRow <= $numRows) {
$currentRow++;
$buffer = fgets($handle, 4096);
echo $buffer."<br>";
}
fclose($handle);
?>
But doesn't it copy the whole file to memory?
A better approach maybe fread()
but it uses the bytes so might also not be the a good approach too.
My file can go into around 100MB so I want it.
If you're already doing stuff on the command line, why not use tail
directly:
$myfile = 'myfile.txt';
$command = "tail -20 $myfile";
$lines = explode("\n", shell_exec($command));
Not tested, but should work without PHP having to read the whole file.
Try applying this logic as it might help: read long file in reverse order fgets
Most f*()
-functions are stream-based and therefore will only read into memory, what should get read.
As fas as I understand you want to read the last $numRows
line from a file. A maybe naive solution
$result = array();
while (!feof($handle)) {
array_push($result, fgets($handle, 4096));
if (count($result) > $numRows) array_shift($result);
}
If you know (lets say) the maximum line length, you can try to guess a position, that is nearer at the end of the file, but before at least $numRows
the end
$seek = $maxLineLength * ($numRows + 5); // +5 to assure, we are not too far
fseek($handle, -$seek, SEEK_END);
// See code above
精彩评论