6

在我的应用程序的某些点写入文件后,我希望强制同步到磁盘。由于它在 Linux 上运行,我可以只运行

Runtime.getRuntime().exec("sync");

但是,我宁愿不介绍 Linux 特定的系统调用,而宁愿使用

java.io.FileDescriptor#sync();

但是,我使用 Apache VFS 在本地文件系统上执行操作,据我所知,它不提供对底层文件描述符的访问。但是我是否需要访问刚刚写入以强制同步的实际文件描述符?例如,我不能只使用任何 FileDescriptor 来调用同步以获得相同的效果吗

FileDescriptor.in.sync();

这会是一种有效的方法吗,结果是否与在 Linux 中调用同步的结果相匹配?

以防万一有人知道是否/如何可以访问 VFS 中的底层 FileDescriptor,了解一下也很有用。

编辑:看来

FileDescriptor.in.sync();

不想在 Linux 上工作(尽管从 Eclipse 运行时它可以在我的 Windows 机器上工作),但是

new FileOutputStream(new File("anyfile")).getFD().sync();

绝对有效,调用它的结果与直接调用 Linux 同步命令的结果相匹配。但是,它涉及打开和关闭冗余文件输出流,因此并不完全理想。任何其他原因这可能是一个坏主意,因为它似乎确实有效?是否有其他方法可以获得可用于同步的 FileDescriptor?

4

1 回答 1

4

我前段时间调查过这样的问题:Question 1 , Question 2

在 Linux 中,java.io.FileDescriptor#sync调用可确保将与描述符关联的文件的修改数据发送到磁盘。(那个便宜的磁盘往往会跳过写入,只将数据放在不可靠的(也就是没有 NVRAM)写入缓存中是一个不同/额外的问题。)它不能保证其他文件的修改数据也会被写回。这不在同步合同或基础fsync POSIX 函数的合同中。

但是,在某些情况下(例如 ext3 在 data=ordered 模式下),文件上的 fsync 会写备份文件系统的修改数据。这真的很有趣,因为这可能会因为其他一些应用程序创建了大量的脏块而产生显着的延迟。

于 2013-03-07T16:37:09.557 回答