阻止在php中读取文件?

阻止在php中读取文件?,php,input,io,filehandle,Php,Input,Io,Filehandle,我想从一个文本文件中读取所有内容并进行回显。但在我阅读时,可能会有更多的行写入文本文件,因此我不希望脚本在到达文件末尾时退出,而是希望它永远等待更多行。这在php中可能吗?这只是一个猜测,但请尝试通过(passthru)一个“tail-f”输出 但是您需要找到一种方法来刷新()缓冲区 我认为更好的解决方案是构建一个ajax站点 将文件的内容读入数组。存储会话中的行数。打印文件的内容 如果行数大于会话数,则每隔x秒向检查文件的脚本启动一个ajax请求,并将结果附加到页面 您可以使用popen(

我想从一个文本文件中读取所有内容并进行回显。但在我阅读时,可能会有更多的行写入文本文件,因此我不希望脚本在到达文件末尾时退出,而是希望它永远等待更多行。这在php中可能吗?

这只是一个猜测,但请尝试通过(passthru)一个“tail-f”输出

但是您需要找到一种方法来刷新()缓冲区


我认为更好的解决方案是构建一个ajax站点

将文件的内容读入数组。存储会话中的行数。打印文件的内容

如果行数大于会话数,则每隔x秒向检查文件的脚本启动一个ajax请求,并将结果附加到页面


您可以使用popen()指令:

$f = popen("tail -f /where/ever/your/file/is 2>&1", 'r');
while(!feof($f)) {
    $buffer = fgets($f);
    echo "$buffer\n";
    flush();
    sleep(1);
}
pclose($f)

睡眠很重要,如果没有睡眠,您将有100%的CPU时间。

这只是一个猜测,但请尝试通过(passthru)一个“tail-f”输出

但是您需要找到一种方法来刷新()缓冲区


我认为更好的解决方案是构建一个ajax站点

将文件的内容读入数组。存储会话中的行数。打印文件的内容

如果行数大于会话数,则每隔x秒向检查文件的脚本启动一个ajax请求,并将结果附加到页面


您可以使用popen()指令:

$f = popen("tail -f /where/ever/your/file/is 2>&1", 'r');
while(!feof($f)) {
    $buffer = fgets($f);
    echo "$buffer\n";
    flush();
    sleep(1);
}
pclose($f)
睡眠很重要,如果没有睡眠,您将有100%的CPU时间。

事实上,当您“回显”睡眠时,它将进入缓冲区。因此,如果在浏览器仍在接收输出时添加了新内容,则需要“附加”新内容。这是不可能的(但有一些方法可以做到)。

事实上,当你“回显”它时,它会进入缓冲区。因此,如果在浏览器仍在接收输出时添加了新内容,则需要“附加”新内容。这是不可能的(但有一些方法可以做到)。

我解决了这个问题

诀窍是使用fopen,当达到eof时,将光标移动到上一个位置并从那里继续读取

<?php
$handle = fopen('text.txt', 'r');
$lastpos = 0;
while(true){
   if (!feof($handle)){
       echo fread($handle,8192);
       flush();
       $lastpos = ftell($handle);
   }else{
       fseek($handle,$lastpos);
   }
}
?>

但是仍然需要消耗大量的cpu,我不知道如何解决这个问题。

我解决了它

诀窍是使用fopen,当达到eof时,将光标移动到上一个位置并从那里继续读取

<?php
$handle = fopen('text.txt', 'r');
$lastpos = 0;
while(true){
   if (!feof($handle)){
       echo fread($handle,8192);
       flush();
       $lastpos = ftell($handle);
   }else{
       fseek($handle,$lastpos);
   }
}
?>


但是仍然会消耗大量cpu,不知道如何解决这个问题。

您也可以使用
filemtime
:获取最新的修改时间戳,发送输出,最后再次将存储的
filemtime
与当前时间戳进行比较


无论如何,如果希望脚本与浏览器(或客户端)同时运行,则应使用块(
fread
flush
)发送输出,然后在最后检查任何更改。如果有任何更改,请重新打开文件并从最新的位置读取(您可以在(!feof())时获取
循环之外的位置)。

您也可以使用
filemtime
:获取最新的修改时间戳,发送输出,最后再次将存储的
filemtime
与当前位置进行比较


无论如何,如果希望脚本与浏览器(或客户端)同时运行,则应使用块(
fread
flush
)发送输出,然后在最后检查任何更改。如果有任何更改,请重新打开该文件并从最新位置读取(您可以在(!feof())
时从
循环之外获取位置)。

这取决于您的目标功能类型。此脚本是否在来自浏览器的请求上下文中执行?这是一个可以无休止地运行的CLI脚本吗?这是一个将从命令行或web服务器运行的PHP脚本吗?命令行脚本但这有什么关系?这取决于您所追求的功能类型。此脚本是否在来自浏览器的请求上下文中执行?这是一个可以无限运行的CLI脚本吗?这是一个将从命令行或web服务器运行的PHP脚本吗?命令行脚本但这有什么关系?事实上,我用tail做了一个解决方案,但它使用了一个消耗所有cpu的无限循环,这就是为什么我想要某种“阻塞”调用。每X秒调用一次是不够的,我需要实时的,它不是一个网站,所以没有ajax。
tail-f
是“实时的”,根本不需要循环或php。popen解决方案几乎和我的完全一样。问题在于睡眠,它会使延迟过大。然后尝试usleep()并尽可能降低,但我猜你的cpu负载越低。我尝试过完全不睡眠,但仍然很慢,可能是从php执行tail命令太慢了。实际上,我用tail做了一个解决方案,但它使用了一个无限循环,消耗了所有cpu,这就是为什么我想要某种“阻塞”调用。每X秒调用一次是不够的,我需要实时的,它不是一个网站,所以没有ajax。
tail-f
是“实时的”,根本不需要循环或php。popen解决方案几乎和我的完全一样。问题是睡眠,它使延迟太大。然后尝试usleep()并尽可能降低,但我猜你越低,cpu负载越重。我现在尝试完全不睡眠,但仍然很慢,可能是php的tail命令执行得太慢。你知道有flush()?你知道有flush()吗?您正忙于循环,当然它会消耗所有CPU。尝试在
fseek
行之后添加一个
usleep(50000)
。这将睡眠50毫秒,这将大大降低CPU使用率,对延迟没有显著影响。为了做得更好,你需要使用inotify(假设你在一个支持它的系统上)。是的,我知道这是因为循环,usleep可以工作,但我不是睡眠解决方案的真正粉丝。尽管如此,inotify似乎对b