如何使用AsynchronousFileChannel异步强制文件

Chr*_*man 5 java asynchronous nio nio2

AsynchronousFileChannelJava中NIO.2 API包含的void force(boolean)方法.

显然这种方法是阻塞的,因为只有在将更改成功写入设备后才能返回.

我正在寻找一种方法来实现相同的目标,而不会阻塞线程.

正如评论中所提到的,这将等同于标准C库函数aio_fsync:http://pubs.opengroup.org/onlinepubs/009695399/functions/aio_fsync.html

Owe*_*wen 0

我有一些代码向文件发送大量写入操作,大部分是在“即发即忘”模式下。有时,我想将更改刷新到磁盘,只是为了让用户有信心,如果电源出现故障,他们不会丢失所有内容。为此,我偶尔会这样做:

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();
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这似乎确实会导致更改反映在磁盘上,并且不会阻塞调用线程。当然,它确实会阻塞通道线程池中的一个线程,从而暂时阻止其他写入完成。

它还有一个缺点,就是CompletionHandler的方法不能抛出异常,因此 catch 调用 catch 块。对于我的应用程序,force不需要绝对确定已完成,因此这不是问题。