【问题标题】:what are the concern regarding simultaneous read and write to a file?同时读取和写入文件有什么问题?
【发布时间】:2015-09-17 03:25:23
【问题描述】:

考虑以下场景:

  1. 进程 1 (Writer) 不断向文件 (sharedFile.txt) 追加一行
  2. 进程 2 (Reader) 不断地从 sharedFile.txt 中读取一行

我的问题是:

在java中是否有可能:

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

演示

进程一(Writer):

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

进程二(Reader):

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

注意:

Writer 进程具有优先权。所以什么都不能干扰它。

【问题讨论】:

标签: java file io filewriter


【解决方案1】:

代码不会崩溃。然而,当到达终点时,读者将终止,即使作者可能仍在写作。您必须以某种方式进行同步!

【讨论】:

  • 不会频繁刷新添加到文件末尾?就像在 Linux 中你可以同时读/写一样。
  • 确实,正如我所说,您可以同时写作和阅读。尽管如此,如果阅读器赶上作者并尝试阅读,它不会等待更多数据,它将返回 EOF 并向 java 流指示已到达文件末尾并且无法读取更多数据.如果您稍后打开另一个流,它将能够读取更多数据,直到您赶上写入器并且再次出现相同的问题。
【解决方案2】:

关注:

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

即使您在没有同步的情况下写入文件,您在读取时也会看到不同的值

【讨论】:

  • 文件状态不一致
  • 你的意思是即使作家在每一行之后都会刷新?
【解决方案3】:

Java 文件 IO 和普通文件不是为同时写入和读取而设计的。要么你的读者会超过你的作者,要么你的读者永远不会读完。

JB Nizet 在他的评论中提供了答案。您在阅读时使用BlockingQueue 来保存写入器数据。要么队列为空,要么阅读器永远不会完成。您可以通过 BlockingQueue 方法检测任何一种情况。

【讨论】:

    【解决方案4】:

    由于您谈论的是进程,而不是线程,因此答案取决于底层操作系统如何管理打开的文件句柄:

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

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

    对于非常快速的非阻塞 I/O,您可能需要考虑通过 Java 的 MappedByteBuffer 进行内存映射文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多