我有一个巨大的日志文件(大约1,000,000行)。我想获取最后一行并使用PHP将其从文件中删除。最快的方法是什么?
我试过了:
$logfile = escapeshellarg("/path/to/logfile");
$lastline = `tail -n 1 "$logfile"`; // obtained the last line
上述方法是否足够有效?以及如何从文件中删除最后一行?
根据Jon的回答,下面是代码:
$buffer_size = 1000;
$fh = fopen("/path/to/logfile", "r+");
fseek($fh, -$buffer_size, SEEK_END);
$content = fgets($fh, 100);
while(strrpos($content, PHP_EOL) != false) {
fseek($fh, -$buffer_size); // move backward for extra -1000
$content = fgets($fh, $buffer_size);
}
$pos_last_eol = strrpos($content, PHP_EOL);
fseek($fh, $pos_last_eol); // seek to that position
ftruncate($fh, ftell($fh));
fclose($fh);
答案 0 :(得分:2)
从大文件中获取和删除最后一行的最快方法是:
strrpos
的内容向后搜索缓冲区,直至找到行尾标记¹ftruncate
切断从找到的行尾开始的文件部分¹支持所有
\n
,\r
,\r\n
会使事情复杂化 小;特别是对于后者,它总是可能发生跨越 跨越两个缓冲区,因此您必须明确注意这一点。²这不是绝对必要的,因为您将要访问所有数据 read已经通过了缓冲区,所以你可以保留一个 复制并保存此操作的成本。在实践中虽然最后 线不会太长,所以它更方便 重新阅读整个事情(C运行时和/或OS文件系统缓存可能会这样做 无论如何都很愚蠢。)
这是任何程序必须要做的。如果您决定通过将前七个步骤卸载到tail
等外部实用程序来“欺骗”,则只需拨打ftruncate
,但,即可从文件中删除该行:如果您不希望在文件中留下尾随行尾字符,请在计算截断的偏移量时小心。