如何在LINUX上用Java实时读取文本文件?

如何在LINUX上用Java实时读取文本文件?,java,linux,stream,real-time,compatibility,Java,Linux,Stream,Real Time,Compatibility,我在caps中加入“ON LINUX”并不是为了让你感到烦恼,而是因为我已经能够在Windows上使用3种不同的文件读取类来实现这一点。 FileIntputStream 缓冲区读取 随机存取文件 (最后两个我很确定,但第一个可能是错误的——我的记忆是baaad。)所有这些对我来说都在windows上运行得很好。 我打算使用这些读卡器来实时逐行读取文本文件,这意味着,当保存此文件的新版本时,会附加一行新行,java程序会读取这行,对其执行某些操作,然后继续检查另一行新行 我曾尝试使用Java 7

我在caps中加入“ON LINUX”并不是为了让你感到烦恼,而是因为我已经能够在Windows上使用3种不同的文件读取类来实现这一点。 FileIntputStream 缓冲区读取 随机存取文件 (最后两个我很确定,但第一个可能是错误的——我的记忆是baaad。)所有这些对我来说都在windows上运行得很好。 我打算使用这些读卡器来实时逐行读取文本文件,这意味着,当保存此文件的新版本时,会附加一行新行,java程序会读取这行,对其执行某些操作,然后继续检查另一行新行

我曾尝试使用Java 7 openJDK、Java 7 Oracle和Java 8 Oracle环境以及所有生成的.jar进行编译。JAR在windows上运行良好,而且由于Java是跨平台的,我认为它们也可以在Linux上运行(对吧?),但我编译的每个版本在Linux上测试时都失败了。 这是由一位运行linux Red Hat的社区论坛成员引起我注意的,没有错误/异常,看起来它正在运行,但就是不起作用。我今天安装了Ubuntu,并亲自尝试:读者可以很好地阅读原始文件,但不会实时“流”文件。对文件的更改不会被注意到。 我很困惑这是怎么可能的,老实说,我很惊讶它没有被提到任何地方(据我所知lol)。希望这意味着我在确保linux兼容性方面犯了一个愚蠢的错误,有人可能会追查到。 感谢所有帮助/答案/解决方法

下面是我试图在程序中实现的代码示例:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Driver {

    public static void main(String[] args) {
        RandomAccessFile reader = null;
        try {
            reader = new RandomAccessFile(new File("/home/citats/csgo/console.log"), "r");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String currLine;
        Boolean done = false;
        while (!done) {
            try {
                if ((currLine = reader.readLine()) != null)
                {
                    System.out.println(currLine);
                    if (currLine.equals("done"))
                        done = true;
                } else
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        reader.close();
    }
}

跟踪文件

要获得类似于
tail-f
的功能,其中您的解决方案正在监视新的文件更新,然后对其进行处理,请参见以下答案:。这篇文章的来源为你的尝试提供了信息。我怀疑有些人会回避你所看到的问题

实现类似结果的另一种非常有趣的方法是使用JavaRX文件,您可以通过javanio安排以更不同步的方式交付新的更改。他们的主页上有一个例子:

import com.github.davidmoten.rx.FileObservable;
进口接收。可观察;
导入java.io.File;
可观察项目=
FileObservable.tailer()
.file(“/var/log/server.log”)
.起始位置(0)
.sampleTimeMs(500)
.chunkSize(8192)
.utf8()
.tailText();
RxJava


有关为什么使用JavaRx的更多信息,请参见

尝试使用较新的NIO类,因为它们可能提供对文件的更直接访问。较旧的IO类可能使用Linux API以只读方式打开文件,该API可能正在访问文件的快照。(我在这里猜测)。我必须在
中添加
抛出异常
,以处理
阅读器周围缺少的
try catch
。关闭
,我还将您的路径更改为
/tmp/abc.log
。然后我做了一个
touch/tmp/abc.log
并运行程序。最后,我做了一个
echo测试>/tmp/abc.log
,我确实看到程序生成了输出。您能提供重现问题的说明吗?我还看到了回送和使用nano通过shell写入文件时的预期输出。但是,当我使用gedit将一行附加到日志中时,我看不到输出。很奇怪。我认为可以安全地假设正在写入日志文件的游戏控制台可能遇到与gedit相同的问题,不管是什么问题!如果对文件进行“cat”,是否看到新行,而没有从程序中看到它?这是正确的Roberto。
import com.github.davidmoten.rx.FileObservable;
import rx.Observable;
import java.io.File; 

Observable<String> items = 
     FileObservable.tailer()
               .file("/var/log/server.log")
               .startPosition(0)
               .sampleTimeMs(500)
               .chunkSize(8192)
               .utf8()
               .tailText();