AsynchronousFileChannel
API是Java NIO.2中的一个API,其中包含void force(boolean)
方法。
显然,此方法是阻塞的,因为它只有在更改成功写入设备后才能返回。
我正在寻找一种方法来实现相同的功能,而不会阻塞线程。
正如评论中提到的那样,这将是标准C库函数aio_fsync
的等效函数:http://pubs.opengroup.org/onlinepubs/009695399/functions/aio_fsync.html
AsynchronousFileChannel
API是Java NIO.2中的一个API,其中包含void force(boolean)
方法。
显然,此方法是阻塞的,因为它只有在更改成功写入设备后才能返回。
我正在寻找一种方法来实现相同的功能,而不会阻塞线程。
正如评论中提到的那样,这将是标准C库函数aio_fsync
的等效函数:http://pubs.opengroup.org/onlinepubs/009695399/functions/aio_fsync.html
我有一些代码,在其中向一个文件发送了大量的写操作,大部分都是以fire-and-forget模式进行的。偶尔,我想要刷新对磁盘的更改,仅仅是为了给用户一些信心,即使断电,他们也不会失去所有数据。为此,我有时会这样做:
channel.write(ByteBuffer.wrap(new byte[0]), 0, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
try {
channel.force(false);
}
catch (Throwable t) {
t.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Object attachment) {
try {
channel.force(false);
}
catch (Throwable t) {
t.printStackTrace();
}
}
});
这似乎会导致磁盘上的更改得到反映,并且不会阻塞调用线程。当然,它会阻塞通道线程池中的一个线程,从而在一段时间内防止其他写入完成。
它还有一个缺点,即CompletionHandler
的方法不能抛出异常,因此需要使用try-catch块。对于我的应用程序,绝对确保force
已完成并不是必需的,因此这不是问题。
SYNC
或DSYNC
选项打开你的文件是你正在寻找的。 - mkrakhin