提问人:Ryan 提问时间:5/11/2015 最后编辑:Ryan 更新时间:5/11/2015 访问量:1346
我怎样才能最有效地读取 php 中大型文本文件的前 n 行?
How can I most efficiently read the first n lines of a large text file in php?
问:
到目前为止,我能够返回整个文件或空字符串。但不是预期的文件的第一行。n
echo head('/path/to/my_file.txt',100); // returns '', or in other versions `1\n1\n...`
function head($filepath, $lines = 1, $adaptive = true) {
// Open file
$f = @fopen($filepath, "rb");
if ($f === false) return false;
// Sets buffer size
if (!$adaptive) $buffer = 4096;
else $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
// Start reading
$output = '';
while($line = fgets($f,$buffer) !== false) {
if (feof($f)) break;
$output .= $line . "\n";
}
// Close file and return
fclose($f);
return trim($output);
}
相比之下,以下函数(源)可以完美地工作:tail
function tail($filepath, $lines = 1, $adaptive = true) {
// Open file
$f = @fopen($filepath, "rb");
if ($f === false) return false;
// Sets buffer size
if (!$adaptive) $buffer = 4096;
else $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
// Jump to last character
fseek($f, -1, SEEK_END);
// Read it and adjust line number if necessary
// (Otherwise the result would be wrong if file doesn't end with a blank line)
if (fread($f, 1) != "\n") $lines -= 1;
// Start reading
$output = '';
$chunk = '';
// While we would like more
while (ftell($f) > 0 && $lines >= 0) {
// Figure out how far back we should jump
$seek = min(ftell($f), $buffer);
// Do the jump (backwards, relative to where we are)
fseek($f, -$seek, SEEK_CUR);
// Read a chunk and prepend it to our output
$output = ($chunk = fread($f, $seek)) . $output;
// Jump back to where we started reading
fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
// Decrease our line counter
$lines -= substr_count($chunk, "\n");
}
// While we have too many lines
// (Because of buffer size we might have read too many)
while ($lines++ < 0) {
// Find first newline and remove all text before that
$output = substr($output, strpos($output, "\n") + 1);
}
// Close file and return
fclose($f);
return trim($output);
}
答:
1赞
fbas
5/11/2015
#1
您只需要计算读取的行数,并在达到$lines后中止。
$i = 0;
while($line = fgets($file) !== false) {
if (feof($file)) break;
$output .= $line . "\n";
if ($i++ >= $lines) {
break;
}
}
2赞
Halayem Anis
5/11/2015
#2
// here the correction => apply parenthesis before ...
while(($line = fgets($f)) !== false) {
if (feof($f)) break;
if ($lines-- == 0) break;
$output .= $line . "\n";
}
评论
0赞
Halayem Anis
5/11/2015
是的,它是!也许您的 TEXT 文件有编码问题?
0赞
Ryan
5/11/2015
这将打印出来 .我以为$line是每行的内容。我错过了什么?$lines打印出来1\n1\n...
9\n8\n...
1赞
Halayem Anis
5/11/2015
我已经更新了我的回复:在测试相等性之前,你必须通过 fgets 影响$line,否则你会得到真/假......
0赞
Ryan
5/11/2015
这很好地解决了它!谢谢!
评论