note 94091 added to function.fseek
| From: | james dot neale at live dot com | Date: | Thu, 15 Oct 2009 19:49:32 +0000 |
| Subject: | note 94091 added to function.fseek | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-161788@lists.php.net to get a copy of this message | ||
I have modified and commented the script from vidmantas dot norkus at uostas dot net. This function
will return lines from anywhere in a file.
It will return 10 lines averaging 300 chars offset by 100 lines in 0.5ms (when using $cx value of
300.) from a 4MB file.
Please email me any comments/fixes etc or anywhere you decide to use it.
<?php
/**
* Read lines from anywhere in a file. Includes basic error checking.
* @param $file File to read
* @param $lines Number of lines to return. Use negative number to return from EOF.
* @param $offset Number of lines to offset output.
* @param $cx Optional chunk multiplier can increase speed depending on line length.
* @return string
*/
function file_read($file,$lines=-10,$offset=0,$cx=50){
if(is_file($file)) {
$output = "";
$bufferOffset = 0;
$bufferStart = 1;
$offset = abs($offset);
if($offset > 0) $offset--;
$max = filesize($file);
$pos = $lines < 0 ? $max : 0;
$chunk = abs($lines) * $cx;
if($chunk > 10000) $chunk = 10000;
if(($f = fopen($file,'r')) == false) return "File read error.";
if($lines < 0) {
while($pos) {
$pos -= $chunk;
if($pos < 0) { $chunk += $pos; $pos = 0;}
fseek($f,$pos);
if(($buffer = fread($f, $chunk)) == false) break;
$bufferOffset += substr_count($buffer, "\n");
if($bufferOffset >= $offset) $output = $buffer.$output;
if($bufferOffset > -$lines + $offset|| $pos == 0) {
$to = $offset;
$offset = -$offset + $lines;
if(-$offset > $bufferOffset + 1) $lines = $bufferOffset - $to;
break;
}
}
} elseif($lines > 0) {
$bufferOffset = 1;
while($pos < $max) {
if(($buffer = fread($f, $chunk)) == false) break;
$bufferOffset += substr_count($buffer, "\n");
if($bufferOffset >= $offset) $output = $buffer.$output;
if($bufferOffset > $lines + $offset || $pos + $chunk >= $max)
{$offset = $offset - $bufferStart + 1; break;}
if($bufferOffset < $offset) $bufferStart = $bufferOffset;
$pos += $chunk;
if($pos > $max) { $chunk = $pos - $max; $pos -= $chunk;}
}
} else {
return "No lines requested.";
}
} else {
return "File does not exist.";
}
$output = str_replace("\r",'', $output);
$temp = explode("\n", trim($output));
$output = implode("\n", array_slice($temp, $offset, abs($lines)));
return !$output ? "No lines at that offset." : $output;
}
# will return the last 10 lines of the file
$contents = file_read("errors.log")
# will return 10 lines offset by 6 lines from the beginning of the file (lines 6 - 15)
$contents = file_read("errors.log", 10, 6)
# speed increase for longer lines
$contents = file_read("errors.log", -100, 0, 300)
?>
----
Server IP: 92.48.74.199
Probable Submitter: 86.11.208.166
----
Manual Page -- http://www.php.net/manual/en/function.fseek.php
Edit -- https://master.php.net/note/edit/94091
Del: integrated -- https://master.php.net/note/delete/94091/integrated
Del: useless -- https://master.php.net/note/delete/94091/useless
Del: bad code -- https://master.php.net/note/delete/94091/bad+code
Del: spam -- https://master.php.net/note/delete/94091/spam
Del: non-english -- https://master.php.net/note/delete/94091/non-english
Del: in docs -- https://master.php.net/note/delete/94091/in+docs
Del: other reasons-- https://master.php.net/note/delete/94091
Reject -- https://master.php.net/note/reject/94091
Search -- https://master.php.net/manage/user-notes.php