使用Java 7 AsynchronousFileChannel附加到文件

时间:2013-12-26 20:59:56

标签: java asynchronous java-7 filechannel

我正在尝试使用AsynchronousFileChannel JAVA 7 API以异步方式编写文件,但是我找不到一种简单的方法来附加到该文件。

API说明指出AsynchronousFileChannel不维护文件位置,您必须指定文件位置。这意味着您必须维护全局文件位置值。此外,这个全局状态应该是原子状的,这样你才能正确递增。

是否有更好的方法使用AsynchronousFileChannel进行更新?

另外,有人可以解释在API中使用Attachment对象吗?

public abstract <A> void write(ByteBuffer  src,
             long position,
             A attachment,
             CompletionHandler<Integer ,? super A> handler)

javadoc说: attachment - 要附加到I / O操作的对象;可以为null

此附件对象的用途是什么?

谢谢!

1 个答案:

答案 0 :(得分:3)

  

此附件对象的用途是什么?

附件是一个可以传递给完成处理程序的对象;将其视为提供背景的机会。您可以将它用于您可以想象的任何事情,从记录到同步或只是忽略它。

  

我正在尝试使用AsynchronousFileChannel JAVA 7 API以异步方式编写文件,但是我找不到一种简单的方法来附加到该文件。

异步通常有点棘手,并且附加到文件本身就是一个串行进程。也就是说,你可以并行完成,但是你必须做一些关于在哪里附加下一个缓冲区内容的簿记。我想它可能看起来像这样(使用频道本身作为&#39;附件&#39;):

class WriteOp implements CompletionHandler<Integer, AsynchronousFileChannel> {
  private final ByteBuffer buf;
  private long position;

  WriteOp(ByteBuffer buf, long position) {
    this.buf = buf;
    this.position = position;
  }

  public void completed(Integer result, AsynchronousFileChannel channel) {
    if ( buf.hasRemaining() ) { // incomplete write
      position += result;
      channel.write( buf, position, channel, this );
    }
  }

  public void failed(Throwable ex, AsynchronousFileChannel channel) {
    // ?
  }
}

class AsyncAppender {
  private final AsynchronousFileChannel channel;
  /** Where new append operations are told to start writing. */
  private final AtomicLong projectedSize;

  AsyncAppender(AsynchronousFileChannel channel) throws IOException {
    this.channel = channel;
    this.projectedSize = new AtomicLong(channel.size());
  }

  public void append(ByteBuffer buf) {
    final int buflen = buf.remaining();
    long size;
    do {
      size = projectedSize.get();
    while ( !projectedSize.compareAndSet(size, size + buflen) );

    channel.write( buf, position, channel, new WriteOp(buf, size) );
  }
}