记录一次httpClient下载文件的坑
用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下载文件的坑相关推荐
- java httpclient 下载文件_httpclient 上传文件、下载文件
/** * 上传文件 * @throws ParseException * @throws IOException */ publicstaticvoidpostFile()throwsParse ...
- 实现在 .net 中使用 HttpClient 下载文件时显示进度
在 .net framework 中,要实现下载文件并显示进度的话,最简单的做法是使用 WebClient 类.订阅 DownloadProgressChanged 事件就行了. 但是很可惜,WebC ...
- 记录一下前端针对下载文件的两种请求方式
之前做了很多下载文件的接口都没习惯进行记录,现在开始规范自己,让自己养成一个随手保存代码的好习惯.写的不足之处请指出,会改正. 说一下前端下载文件常用的两种方式,get请求和post请求 get请求相 ...
- Delphi XE8 用HttpClient下载文件
Xe8提供了THttpClient,发送Web请求就简单多了! 我用他下载一个文件,代码变的非常简洁. 遇到的问题就是用TFileStream时,在Android下无法写成文件,注意,是Android ...
- 记录一次ABP下载模板的坑
1.拉取ABP官网的模板的最新代码,我的代码结构是这样的 https://aspnetboilerplate.com/Templates 环境安装的部分我就不说明了.node.js npm 等等部分 ...
- 使用OkHttp 下载文件无进度回调 踩坑
一.踩坑速记 1. 未添加header指定服务器采用何种压缩方式导致下载进度异常 描述:使用OkHttp3执行文件下载(服务端有nginx反向代理服务器进行压缩),获取回调中文件总大小为0或负值,导致 ...
- java网上下载文件
java下载文件 1.使用httpClient下载文件: /* *url:资源的地址:http://***.**.***.**.a.mp4 * */ public void downLoadFile( ...
- Python requests 下载文件
0x00 前言 记录一下Python requests 下载文件的相关内容,每次都是搜别人的不如自己做一做笔记. 0x01 可调用方法 先存一个比较简单地,等以后有用到的话,再进行扩充 def dow ...
- python下载文件暂停恢复_python下载文件记录黑名单的实现代码
具体代码如下所示: #!/usr/bin/python # -*- coding: GBK -*- # -*- coding: UTF-8 -*- from ftplib import FTP imp ...
- python下载后是黑的_python下载文件记录黑名单的实现代码
具体代码如下所示: #!/usr/bin/python # -*- coding: GBK -*- # -*- coding: UTF-8 -*- from ftplib import FTP imp ...
最新文章
- 学习3dmax(四)
- 考研国家线罕见大幅上涨,12个学科涨幅10分以上,超300万人将落榜
- 让我们一起Go(十三)
- UBOOT手动设置环境变量
- yii2数组转为对象_好程序员Java学习路线分享java为什么不支持泛型数组
- boost::process::pipe相关的测试程序
- 3.1_ 6_ 基本分页存储管理的基本概念
- oc c语言,OC之C语言的基础知识
- PREEMPT_RT 3.18.136 实时时延评估
- 微信 iOS 版正式支持深色模式;谷歌宣布彻底取消I/O开发者大会;Visual Studio 2019 16.5发布|极客头条...
- ibm中文语音识别输入系统
- 分享:ViewState压缩方法
- lenneth -- 基于koa2 的web极简框架
- IPD解读——IPD流程
- Android Studio连接MySQL:问题解决:虚拟机无法连接本地SQL,coon总为空
- 生活中的设计模式之状态(State)模式
- c语言常用颜色种类,C语言常用颜色种类(国外英语资料).doc
- 笔记本电脑怎样当无线服务器,笔记本当无线路由器怎么设置【详细步骤】
- Azure-发布个人静态网站
- 【键盘】jQuery+CSS3模拟键盘事件(精)