0

sonatype async http client(https://github.com/sonatype/async-http-client)を使用して、非同期ファイルのアップロードを進行させて実装しようとしています。

ドキュメントで提案されている方法を試しました。転送リスナーを使用します。 http://sonatype.github.com/async-http-client/transfer-listener.html

TransferListenerインターフェースのonBytesSentを実装しました(テストと同じように):

public void onBytesSent(ByteBuffer byteBuffer) {

     System.out.println("Total bytes sent - ");
     System.out.println(byteBuffer.capacity());
}

次に、別のスレッドで(アプリをブロックしたくないため)、次のことを実行しようとしました。

TransferCompletionHandler tl = new TransferCompletionHandler();
tl.addTransferListener(listener);

asyncHttpClient.preparePut(getFullUrl(fileWithPath))
      .setBody(new BodyGenerator() {
           public Body createBody() throws IOException {
                return new FileBodyWithOffset(file, offset);
           }
       })
       .addHeader(CONTENT_RANGE, new ContentRange(offset, localSize).toString())
       .execute(handler).get();

すべて順調。ファイルは正しく、非常に高速にアップロードされます。しかし、問題は-アップロードが終了した後onBytesSentにのみTransferListenerからメッセージを受け取っていることです。たとえば、アップロードは10分で完了します。そして、その10分間、私は何も得られません。その後、すべてがコンソールに印刷されます。

このコードの何が問題なのか理解できません。ドキュメントをフォローしようとしました。

上記のコードをメインスレッドで実行しようとしましたが、どちらも機能しませんでした。

たぶん、このクライアントを使用してアップロード進行状況リスナーを実装するのは間違った方法ですか?

4

1 に答える 1

2

自分で答えます。TransferListenerの問題を解決できませんでした。だから私は別の方法を試しました。

私はprogresslogickをBodyインターフェース実装内(readメソッド内)に配置しました:

public class FileBodyWithOffset implements Body {

    private final ReadableByteChannel channel;

    private long actualOffset;

    private final long contentLength;

    public FileBodyWithOffset(final File file, final long offset) throws IOException {

        final InputStream stream = new FileInputStream(file);

        this.actualOffset = stream.skip(offset);

        this.contentLength = file.length() - offset;

        this.channel = Channels.newChannel(stream);
    }


    public long getContentLength() {

        return this.contentLength;
    }

    public long read(ByteBuffer byteBuffer) throws IOException {

        System.out.println(new Date());

        actualOffset += byteBuffer.capacity();

        return channel.read(byteBuffer);
    }

    public void close() throws IOException {

        channel.close();
    }

    public long getActualOffset() {

        return actualOffset;
    }
}

多分それは汚いトリックですが、少なくともそれは機能します。

于 2012-05-14T19:46:03.217 に答える