使用Java 7的AsynchronousFileChannel追加文件

4
我正在尝试使用AsynchronousFileChannel JAVA 7 API以异步方式编写文件,但是我找不到一种简单的方法来追加文件。API说明指出,AsynchronousFileChannel不维护文件位置,因此您必须指定文件位置。这意味着您必须维护全局文件位置值。此外,这个全局状态应该是原子的,以便您正确地增加它。
有没有更好的方法使用AsynchronousFileChannel进行更新?
此外,请问有人能解释一下API中附件对象的用途吗?
public abstract <A> void write(ByteBuffer  src,
             long position,
             A attachment,
             CompletionHandler<Integer ,? super A> handler)

javadoc中写道:

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

这个attachment对象有什么用呢?

谢谢!

2个回答

3
这个附件对象有什么用处?
附件是一个对象,你可以将它传递给完成处理程序;把它看作提供上下文的机会。你可以将其用于几乎任何你能想象到的事情,从日志记录到同步或者只是简单地忽略它。
我正在尝试使用AsynchronousFileChannel JAVA 7 API以异步方式写入文件,但是我找不到一种简单的方法来追加文件。
异步通常比较棘手,并且向文件追加是一个固有的串行过程。尽管如此,你可以并行进行,但是你必须对下一个缓冲区内容追加的位置进行一些簿记。我想它可能看起来像这样(使用通道本身作为“附件”):
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) );
  }
}

我已经有一段时间没有发布这个问题了,但这似乎应该可以工作! - bsam
append 方法最后一行的 position 在作用域中未定义。它应该是什么? - Re Captcha

2
我刚刚使用了channel.size()作为位置。 在我的情况下,文件不会被多个线程修改,只有一个线程打开并写入该文件,这似乎目前可行。
如果有人知道这是错误的做法,请提出意见。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接