5
回答
HttpClient发送请求下载大文件时一直阻塞,直到下载完后才执行代码
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

目前在用asyncClient,使用Future接口阻塞线程获取HttpResponse,然后getEntity().getContent()读取字节流

测试时都是找各种图片的URL,阻塞时间有些长,开头我还以为是本地网络有些延迟。

代码写得差不多的时候,拿大文件的URL去测试,看着流量监控,数据一直在下载,而程序一直没响应。。。代码里设有时间限制,都直接给抛出超时异常了。主线程没结束,但asyncClient依然下载那些数据。。。假如我只想获取HTTP响应头部,甚至要有过滤,那岂不是在浪费时间?


有办法禁止预下载么?


举报
goto-array
发帖于3年前 5回/1K+阅
共有5个答案 最后回答: 3年前

你将代码写到同步线程调用的FutureCallback中去了。

 httpClient.execute(producer, consumer, 这里是主线程);
下载文件的时候,你收到的response其实是一个文件头,而getEntity().getContent()才是开始接收文件数据,所以你的getEntity().getContent()代码应该写在consumer中,而非Callback中,因为Callback其实是在主线程中执行的。
--- 共有 1 条评论 ---
goto-array我也试着实现consumer,但是没想象中那么好使。想在responseReceived里做过滤,然后再决定要不要下载数据;而实际情况是consumer处于被动回调,没有显式方法来反馈否定下载信号,即使是onsumeContent方法,ContentDecoder也有些预读,而且在确认要下载的情况下,该方法接受数据时都要反复地判断头部过滤。 3年前 回复

引用来自“yunfound”的评论

你将代码写到同步线程调用的FutureCallback中去了。

 httpClient.execute(producer, consumer, 这里是主线程);
下载文件的时候,你收到的response其实是一个文件头,而getEntity().getContent()才是开始接收文件数据,所以你的getEntity().getContent()代码应该写在consumer中,而非Callback中,因为Callback其实是在主线程中执行的。
不是的,execute方法始终返回Future接口,然后调用其get方法就能阻塞线程,直到有HTTP响应;解除阻塞后,接着就执行我的代码。

虽然你以为我的代码写到了FutureCallback里去,作用也大致一样,不过前面我说的get方法能做到超时限制,防止请求时间过长。在以往的测试中,有些请求发出之后就毫无踪影,就像卡住似的,所以才搞个超时限制,而FutureCallback则实现不了这样的需求。

走回正题,你说的HttpAsyncResponseConsumer的确能解决预下载问题,跟FutureCallback相似,后来我也查了下超时,设置要在请求处下手,我的方向应该是搞错了。Future接口的超时,不该用在连接上,而应是对HttpResponse或其自产生的完整实体的未来期待结果。
--- 共有 1 条评论 ---
yunfoundGood!!! 我没用过这个工具,学习了!!! 3年前 回复
顶部