0

我正在尝试使用 sonatype 异步 http 客户端 - 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();

一切都很好。文件上传正确且速度非常快。但问题是 - 我仅在上传完成后才从TransferListeneronBytesSent收到消息。例如,上传在 10 分钟内完成。在那 10 分钟内,我什么也得不到。只有在那之后,所有内容都打印在控制台上。

我无法弄清楚这段代码有什么问题。我只是尝试遵循文档。

我试图在主线程中执行上面的代码,它也没有工作。

也许使用这个客户端实现上传进度监听器是错误的方法?

4

1 回答 1

2

我会自己回答。我没有设法解决 TransferListener 的问题。所以我尝试了另一种方式。

我已经将进度逻辑放在 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 回答