4

JAVA 7 API を使用して非同期でファイルを書き込もうとしてAsynchronousFileChannelいますが、ファイルに追加する簡単な方法が見つかりませんでした。

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 操作にアタッチするオブジェクト。ヌルにすることができます

この添付オブジェクトの用途は何ですか?

ありがとう!

4

2 に答える 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) );
  }
}
于 2015-07-23T15:28:54.827 に答える