2012-05-13 34 views
0

我想用sonatype async http client-https://github.com/sonatype/async-http-client实现异步文件上传进度。Java Sonatype异步HTTP客户端上传进度

我尝试了文档中建议的方法。使用传输监听器。 http://sonatype.github.com/async-http-client/transfer-listener.html

我实现onBytesSent TransferListener接口(就像试验):

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分钟内,我什么也得不到。只有在这之后,所有东西都印在控制台上。

我不明白这段代码有什么问题。我只是试图按照文档。

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

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

回答

2

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

我已经把进度logick体内接口实现(读法里):

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; 
    } 
} 

也许这是一个肮脏的把戏,但至少它的工作原理。