如何刷新’RandomAccessFile’(java)?
我在java中使用RandomAccessFile:
file = new RandomAccessFile(filename, "rw"); ... file.writeBytes(...);
如何确保将此数据刷新到操作系统? 没有file.flush()方法。 (请注意,我实际上并不期望它是物理写入的,我很满意它被刷新到操作系统,因此数据将在tomcat崩溃中存活,但不一定是意外的服务器断电)。
我在Linux上使用tomcat6。
提供.flush()
方法的唯一类是那些实际维护自己的缓冲区的类。 由于java.io.RandomAccessFile
本身不维护缓冲区,因此不需要刷新它。
仔细看看RandomAccessFile构造函数javadoc:
“rws”和“rwd”模式的工作方式与FileChannel类的force(boolean)方法非常相似,分别传递true和false参数,但它们始终适用于每个I / O操作,因此通常更有效。 如果文件驻留在本地存储设备上,那么当调用此类的方法返回时,可以保证该调用对该文件所做的所有更改都将写入该设备 。 这对于确保在系统崩溃时不会丢失关键信息非常有用。 如果文件不驻留在本地设备上,则不会进行此类保证。
您可以使用getFD().sync()
方法。
这是我在我的应用程序中所做的:
rf.close(); rf = new RandomAccessFile("mydata", "rw");
与getFd()。sync()相比,这可以使性能提高3-4倍,与“rws”模式相比提高5-7倍
完全解决原始问题提出的问题:将未保存的数据传递给操作系统和JVM。 不物理写入磁盘,因此不会引入烦人的延迟
我带着同样的好奇心来到这里。
我真的无法想象需要在操作系统上刷新什么,而不一定需要刷新到磁盘部分。
在我看来,
与托管刷新概念相匹配的最好的事情是getFD().sync()
,正如@AVD所说,
try(RandomAccessFile raw = new RandomAccessFile(file, "rw")) { raw.write... raw.write... raw.getFD().sync(); raw.wirte... }
看起来,通过它的文档,它的工作原理非常类似于FileChannel #force(boolean)对true
。
现在, "rws"
和"rwd"
看起来好像在FileChannel
open
分别指定StandardOpenOption#SYNC
和StandardOpenOption#DSYNC
。
try(RandomAccessFile raw = new RandomAccessFile(file, "rws")) { raw.write... raw.write... raw.wirte... // don't worry be happy, woo~ hoo~ hoo~ }
我知道你不能..
这里有一些相关的链接: http : //www.cs.usfca.edu/~parrt/course/601/lectures/io.html和这里: http : //tutorials.jenkov.com/java-io/bufferedwriter.html