关于同时读取和写入文件的关注点是什么?

what are the concern regarding simultaneous read and write to a file?

考虑以下场景:

  1. 进程 1 (Writer) 连续向文件追加一行 (sharedFile.txt)
  2. 进程2(Reader)连续从sharedFile.txt
  3. 中读取一行

我的问题是:

在java中是否有可能:

  1. Reader 进程以某种方式崩溃 Writer 进程(即中断 Writer 进程)?
  2. Reader 一些如何知道何时停止读取文件的纯粹基于文件统计信息(Reader 不知道其他人是否正在写入文件)?

展示

进程一(作者):

...
while(!done){
 String nextLine;//process the line
 writeLine(nextLine);
 ...
}
...

进程二(Reader):

...
while(hasNextLine()){
  String nextLine= readLine();
  ...
}
...

注意:

Writer 进程优先。所以没有什么可以干扰它。

代码不会崩溃。但是,reader 将在到达末尾时终止,即使作者可能仍在写作。您将不得不以某种方式进行同步!

关注:

您的 reader 线程可以读取过时值,即使您认为另一个编写器线程已更新变量值也是如此

如果不存在同步,即使您写入文件,您在读取时也会看到不同的值

Java 文件 IO 和纯文件不是为同时写入和读取而设计的。要么你的 reader 会赶上你的作家,要么你的 reader 永远写不完。

JB Nizet provided the answer in his comment. You use a BlockingQueue 在您阅读时保存作者数据。队列要么清空,要么 reader 永远不会完成。您可以通过 BlockingQueue 方法来检测这两种情况。

既然你说的是进程,而不是线程,答案取决于底层OS如何管理打开的文件句柄:

  1. 在我熟悉的每个 OS 上,Reader 永远不会使编写器进程崩溃,因为 Reader 的文件句柄只允许读取。在 Linux 上,系统调用 Reader 可能会在底层 OS 上调用 open(2),带有 O_RDONLY 标志,lseek(2)read(2) -- 已知不会干扰 Writer 正在调用的系统调用,例如 write(2).
  2. Reader 很可能不知道什么时候停止阅读大多数 OS。更准确地说,在某些读取尝试中,它将接收到零作为读取字节数,并将其视为 EOF(文件结尾)。就在这个时候,可能有Writer准备向文件追加一些数据,但是Reader无法知道。

如果你需要一种方法让两个进程通过文件进行通信,你可以使用一些额外的文件来实现,这些文件在 Readers 和 Writers 之间传递元信息,例如当前是否有 Writer 运行。在文件中引入一些结构也很有用(例如,每个 Writer 都会向文件附加一个字节,指示写入过程正在进行)。

对于非常快速的非阻塞 I/O,您可能需要通过 Java 的 MappedByteBuffer.

考虑内存映射文件