同时读取和写入文件"在不同的过程中

时间:2013-07-19 12:08:48

标签: java file io ipc

我有两个Java进程ProcessorSimulatorSimulator每5秒向File X写一条规定的数据记录(10行文本)。 Processor不断读取此文件,等待令牌指示有效记录。代码是这样的(对文件名有一些替换):

Simulator,每5秒:

FileWriter fileWriter = new FileWriter(DATA_FILE, true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(DATA);
bufferedWriter.close();

Processor中,不断:

mScanner = new Scanner(new BufferedReader(
        new FileReader(DATA_FILE)));
mScanner.useLocale(Locale.UK);

while (true) {              
    while (mScanner.hasNextLine()) {
    // Parse the data bundle.
    if (parseDataBundle()) {
            ...
        }
    }
}

以前,Processor已挂钩到InputStream,使用Scanner(已正确配置)在数据到达时读取数据没有问题。

在这里,通过在记事本中刷新文件,我可以看到数据在生成时正确写入。但是当使用文件而不是InputStream时,永远不会到达if ( parseDataBundle()) {行。

我做错了什么? Processor似乎拥有文件资源,因为我无法在运行时删除它。我的直觉认为这可能与滥用并发性有关。

2 个答案:

答案 0 :(得分:2)

我会说这是对文件的滥用。文件不是为消息传递而设计的。一旦到达文件的末尾,就是这样。避免这种情况的唯一方法是确保只在知道有更多数据时才读取(通过检查长度)。使用文本时这会更复杂。

您可以使用带文字的文件,但这很棘手。您必须有一个线程轮询文件大小,当它发生更改时,只读取添加的字节(不再是)。这可以写入管道。您的读取线程可以使用InputStreamReader和BufferedReader从管道读取。


要更改轮询间隔,您可以使用升级的休眠间隔,例如

long lastSize = 
int maxSleep = 5000, sleep = 200;
while(!Thread.currentThread().isInterrupted()) {
     long size = file.length();
     if (size > lastSize) {
        copyData(size - lastSize);
        lastSize = size;
        sleep = 200;
     } else {
        Thread.sleep(sleep);
        sleep += 200;
        if (sleep > maxSleep)
            sleep = maxSleep;
}

这种方法的好处在于,它可以调整到获得消息的速率。

答案 1 :(得分:0)

Java NIO提供文件锁定支持。根据底层操作系统 - 您可以在写入完成后写入和释放锁定时获取文件的独占锁定。另一个进程可以尝试获取锁,如果有,则读取文件并释放它。轮询直到获得锁定。希望你明白这个主意。查看FileChannel#lock() API。