FileInputStream和FileOutputStream到同一个文件:read()是否保证看到“之前发生过”的所有write()?

问题描述 投票:8回答:4

我使用文件作为大数据的缓存。一个线程按顺序写入,另一个线程按顺序读取它。

我可以确定在一个线程中编写的所有数据(由write()编写)可以是来自另一个线程的read(),假设在Java内存模型方面存在适当的“先发生”关系吗?这种行为是否有记录?

在我的JDK中,FileOutputStream不会覆盖flush(),而OutputStream.flush()是空的。这就是我想知道的原因......

有问题的流程完全由我完全控制的类所有。保证每个流只能由一个线程访问。我的测试显示它按预期工作,但我仍然想知道这是否有保证和记录。

另见this related discussion

java concurrency stream
4个回答
10
投票

假设您使用的是posix文件系统,那么是的。

* nix上的FileInputStreamFileOutputStream在内部使用读写系统调用。写的文件说reads will see the results of past writes

在成功返回常规文件的write()之后:

从该写入修改的文件中每个字节位置的任何成功read()都将返回该位置的write()指定的数据,直到再次修改这些字节位置。

我很确定Windows上的ntfs将具有相同的read() write()保证。


4
投票

你不能谈论你的FileInputStreamFileOutputStream对象之间的Java内存模型之间的“发生之前”关系,因为它们不共享任何内存或线程。 VM可以自由重新排序,只是为了满足您的同步要求。如果在没有应用程序级缓冲的情况下在读写之间进行适当的同步,那么您就是安全的。

然而,FileInputStreamFileOutputStream共享一个文件,这会将操作系统留给操作系统,在按顺序写入后,您可以期望读取主流操作系统中的操作系统。


0
投票

不,你需要flush()Streams(至少对于Buffered(输入|输出)Streams),否则你可能在缓冲区中有数据。

也许你需要一个concurrent data structure


0
投票

如果FileOutputStream没有覆盖flush(),那么我认为你可以确定write()写的所有数据都可以被read()读取,除非你的操作系统对数据做了一些奇怪的事情(比如启动一个等待硬盘驱动器以正确的速度旋转而不是阻塞等,这样它就不会立即写入。

© www.soinside.com 2019 - 2024. All rights reserved.