从文件中读取最后一行

Bog*_*scu 31 php file-io file

我遇到了一个问题.我在Linux机器上登录,其中写了几个正在运行的进程的输出.这个文件有时会非常大,我需要从该文件中读取最后一行.

问题是这个动作将经常通过AJAX请求调用,当该日志的文件大小超过5-6MB时,它对服务器来说并不好.所以我想我必须阅读最后一行,但不要读取整个文件并通过它或将其加载到RAM中,因为这只会加载到我的盒子中.

是否有任何针对此操作的优化,以便它运行顺畅,不会损害服务器或杀死Apache?

我有的其他选择是,exec('tail -n 1 /path/to/log')但它听起来不太好.

稍后编辑:我不想把文件放在RAM中,因为它可能会变得很大.fopen()不是一种选择.

Ion*_*tan 45

这应该工作:

$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);
}

echo $line;
Run Code Online (Sandbox Code Playgroud)

  • `fopen()`的行为不像`file_get_contents()` (21认同)
  • 你是什​​么意思,你不想阅读文件?我不是在内存中读取整个文件.我只是打开一种指向它的指针,然后通过char查找它.这是处理大文件的最有效方法. (6认同)
  • 我最后重复了最后一个角色.当我的最后一行是`</ rss>`时,这段代码将`</ rss >>`放入`$ line`.为了解决这个问题,我将`$ cursor - `的两个实例都改成了` - $ cursor`. (2认同)

Naw*_*Man 19

使用fseek.你寻找最后一个位置并向后寻找它(使用ftell告诉当前位置),直到找到"\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--);
}
Run Code Online (Sandbox Code Playgroud)

注意:我没有测试过.您可能需要进行一些调整.

更新:感谢Syntax Error您指出空文件.

:-D

UPDATE2:Fixxed另一个语法错误,缺少分号 $LastLine = ""


sli*_*kts 6

你正在寻找fseek功能.有一些工作示例,说明如何在那里的注释部分读取文件的最后一行.


Abd*_*him 6

这是Ionu的代码?G·斯坦

我稍微修改了您的代码并使其成为可重用的函数

function read_last_line ($file_path){



$line = '';

$f = fopen($file_path, '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);
}

return $line;
}
Run Code Online (Sandbox Code Playgroud)

echo read_last_line('log.txt');

你会得到最后一行