用httpClient模拟浏览器下载文件的代码,网上是很多的,自己copy了一个就高兴的用起来,下载了几百个文件之后,MD发现所有下载的文件都是损坏的、根本打不开,这TM就尴尬了啊,用浏览器下载是没问题的啊。

下面看一下当时用的代码:

 private static void down(String url, String path, int index) {CloseableHttpClient httpclient = HttpClients.createDefault();HttpGet httpGet = new HttpGet(url);// 这个地方根据浏览器里的内容复制过来httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");httpGet.setHeader("Connection", "keep-alive");httpGet.setHeader("Cookie", "XXXXX浏览器里的cookie复制过来就可以");httpGet.setHeader("Host", "XX.XX.XX");try {CloseableHttpResponse response = httpclient.execute(httpGet);HttpEntity httpEntity = response.getEntity();InputStream in = httpEntity.getContent();String fileName = getFileName(response);File file = new File(path + fileName);FileOutputStream fOut = new FileOutputStream(file);// IOUtils.copy(in,fOut);byte[] buffer = new byte[4*1024];while (in.read(buffer) != -1) {fOut.write(buffer);}fOut.flush();in.close();fOut.close();System.out.println(index+"=============ok================" + path + fileName);} catch (IOException e) {e.printStackTrace();}}

坑就坑在这个地方:

while (in.read(buffer) != -1) {fOut.write(buffer);
}

httpClient传输过来的流不一定会每次把 byte[] buffer写满,这种写法在本地复制文件的时候是可以的,但是网络流上就会出大问题,也就是out.write()的起终点没有显示的指定而是默认取buffer.length,每次缓存基本上都是读不满的,所以导致写入大量的空流到文件中。这也长了个教训,以后在调用API的时候能显示指定的就不要用默认值,你不知道会出什么问题。

正确的写法是这样的:

int n = 0;
while ((n=in.read(buffer)) != -1) {fOut.write(buffer,0,n);
}

或者有工具类可以用 IOUtils.copy(in,out);这个方法里的实现是一样的。

另外:获取文件名的方法附上:

private static String getFileName(CloseableHttpResponse response) {String fileName = "";Header header = response.getFirstHeader("Content-disposition");//System.out.println(JSONObject.toJSONString(response));//System.out.println(JSONObject.toJSONString(header));if (header != null) {HeaderElement[] headerElements = header.getElements();NameValuePair nameValuePair = headerElements[0].getParameterByName("filename");fileName = nameValuePair.getValue();//System.out.println("============fileName==============" + fileName);//System.out.println(nameValuePair.getName());}return fileName;}

记录一次httpClient下载文件的坑相关推荐

  1. java httpclient 下载文件_httpclient 上传文件、下载文件

    /** * 上传文件 * @throws  ParseException * @throws  IOException */ publicstaticvoidpostFile()throwsParse ...

  2. 实现在 .net 中使用 HttpClient 下载文件时显示进度

    在 .net framework 中,要实现下载文件并显示进度的话,最简单的做法是使用 WebClient 类.订阅 DownloadProgressChanged 事件就行了. 但是很可惜,WebC ...

  3. 记录一下前端针对下载文件的两种请求方式

    之前做了很多下载文件的接口都没习惯进行记录,现在开始规范自己,让自己养成一个随手保存代码的好习惯.写的不足之处请指出,会改正. 说一下前端下载文件常用的两种方式,get请求和post请求 get请求相 ...

  4. Delphi XE8 用HttpClient下载文件

    Xe8提供了THttpClient,发送Web请求就简单多了! 我用他下载一个文件,代码变的非常简洁. 遇到的问题就是用TFileStream时,在Android下无法写成文件,注意,是Android ...

  5. 记录一次ABP下载模板的坑

    1.拉取ABP官网的模板的最新代码,我的代码结构是这样的 https://aspnetboilerplate.com/Templates 环境安装的部分我就不说明了.node.js  npm 等等部分 ...

  6. 使用OkHttp 下载文件无进度回调 踩坑

    一.踩坑速记 1. 未添加header指定服务器采用何种压缩方式导致下载进度异常 描述:使用OkHttp3执行文件下载(服务端有nginx反向代理服务器进行压缩),获取回调中文件总大小为0或负值,导致 ...

  7. java网上下载文件

    java下载文件 1.使用httpClient下载文件: /* *url:资源的地址:http://***.**.***.**.a.mp4 * */ public void downLoadFile( ...

  8. Python requests 下载文件

    0x00 前言 记录一下Python requests 下载文件的相关内容,每次都是搜别人的不如自己做一做笔记. 0x01 可调用方法 先存一个比较简单地,等以后有用到的话,再进行扩充 def dow ...

  9. python下载文件暂停恢复_python下载文件记录黑名单的实现代码

    具体代码如下所示: #!/usr/bin/python # -*- coding: GBK -*- # -*- coding: UTF-8 -*- from ftplib import FTP imp ...

  10. python下载后是黑的_python下载文件记录黑名单的实现代码

    具体代码如下所示: #!/usr/bin/python # -*- coding: GBK -*- # -*- coding: UTF-8 -*- from ftplib import FTP imp ...

最新文章

  1. 学习3dmax(四)
  2. 考研国家线罕见大幅上涨,12个学科涨幅10分以上,超300万人将落榜
  3. 让我们一起Go(十三)
  4. UBOOT手动设置环境变量
  5. yii2数组转为对象_好程序员Java学习路线分享java为什么不支持泛型数组
  6. boost::process::pipe相关的测试程序
  7. 3.1_ 6_ 基本分页存储管理的基本概念
  8. oc c语言,OC之C语言的基础知识
  9. PREEMPT_RT 3.18.136 实时时延评估
  10. 微信 iOS 版正式支持深色模式;谷歌宣布彻底取消I/O开发者大会;Visual Studio 2019 16.5发布|极客头条...
  11. ibm中文语音识别输入系统
  12. 分享:ViewState压缩方法
  13. lenneth -- 基于koa2 的web极简框架
  14. IPD解读——IPD流程
  15. Android Studio连接MySQL:问题解决:虚拟机无法连接本地SQL,coon总为空
  16. 生活中的设计模式之状态(State)模式
  17. c语言常用颜色种类,C语言常用颜色种类(国外英语资料).doc
  18. 笔记本电脑怎样当无线服务器,笔记本当无线路由器怎么设置【详细步骤】
  19. Azure-发布个人静态网站
  20. 【键盘】jQuery+CSS3模拟键盘事件(精)

热门文章

  1. 国际科学数据服务平台 - csdb_拔剑-浆糊的传说_新浪博客
  2. 哄女票超简单程序代码(日常小惊喜)
  3. 最高响应比调度算法_高响应比调度算法(c语言程序实现)
  4. ArcMAP问题集锦(一)
  5. java递归生成无限层级的树--分类管理
  6. 【转】所需即所获:像 IDE 一样使用 vim
  7. Unity小组工程实践项目《最强外卖员》策划案纠错文档
  8. 跨境电商指南:如何处理客户投诉
  9. Hive 窗口函数lead、lag
  10. Nginx源码分析(25篇)