简体   繁体   English

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

[英]FileInputStream and FileOutputStream to the same file: Is a read() guaranteed to see all write()s that "happened before"?

I am using a file as a cache for big data.我正在使用文件作为大数据的缓存。 One thread writes to it sequentially, another thread reads it sequentially.一个线程按顺序写入它,另一个线程按顺序读取它。

Can I be sure that all data that has been written (by write() ) in one thread can be read() from another thread, assuming a proper "happens-before" relationship in terms of the Java memory model?我能否确定在一个线程中写入(通过write() )的所有数据都可以从另一个线程read() ,假设在 Java 内存模型方面存在正确的“发生在之前”的关系? Is this behavior documented?这种行为有记录吗?

In my JDK, FileOutputStream does not override flush() , and OutputStream.flush() is empty.在我的 JDK 中, FileOutputStream不会覆盖flush() ,并且OutputStream.flush()为空。 That's why I'm wondering...这就是为什么我想知道...

The streams in question are owned exclusively by a class that I have full control of.有问题的流完全由我完全控制的类拥有。 Each stream is guaranteed to be accesses by one thread only.每个流都保证只能被一个线程访问。 My tests show that it works as expected, but I'm still wondering if this is guaranteed and documented.我的测试表明它按预期工作,但我仍然想知道这是否有保证和记录。

See also this related discussion .另请参阅此相关讨论

Assuming you are using a posix file system, then yes.假设您使用的是 posix 文件系统,那么是的。

FileInputStream and FileOutputStream on *nix use the read and write system calls internally. *nix 上的FileInputStreamFileOutputStream在内部使用读写系统调用。 The documentation for write says that reads will see the results of past writes , write 的文档说读取将看到过去写入的结果

After a write() to a regular file has successfully returned:在对常规文件的 write() 成功返回后:

Any successful read() from each byte position in the file that was modified by that write shall return the data specified by the write() for that position until such byte positions are again modified.从文件中被该写入修改的每个字节位置的任何成功 read() 都应返回该位置的 write() 指定的数据,直到再次修改此类字节位置。

I'm pretty sure ntfs on windows will have the same read() write() guarantees.我很确定 Windows 上的 ntfs 将具有相同的read() write()保证。

You can't talk about "happens-before" relationship in terms of the Java memory model between your FileInputStream and FileOutputStream objects since they don't share any memory or thread.您不能根据FileInputStreamFileOutputStream对象之间的 Java 内存模型谈论“发生在之前”的关系,因为它们不共享任何内存或线程。 VM is free to reorder them just honoring your synchronization requirements. VM 可以自由地重新排序它们,只是为了满足您的同步要求。 When you have proper synchronization between reads and writes without application level buffering, you are safe.当您在没有应用程序级缓冲的情况下在读取和写入之间进行适当的同步时,您是安全的。

However FileInputStream and FileOutputStream share a file, which leaves things up to the OS which in main stream ones you can expect to read after write in order.但是FileInputStreamFileOutputStream共享一个文件,这将事情留给操作系统,在主流文件中,您可以按顺序读取后读取。

No, you need to flush() the Streams (at least for Buffered(Input|Output)Streams), otherwise you could have data in a buffer.不,您需要刷新()流(至少对于缓冲(输入|输出)流),否则您可能在缓冲区中有数据。

Maybe you need a concurrent data structure ?也许你需要一个并发数据结构

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM