关于Java/Kotlin下载图片,图片打开不能显示问题…
2020-02-24 16:05:21来源:博客园 阅读 ()
关于Java/Kotlin下载图片,图片打开不能显示问题探究
图片下载其实是个很简单的功能,通过IO流从在线地址获取流,之后将流输出到文件即可完成下载功能,但是,最近我发现某个网站中的图片下载成功,但是打开却是无法打开,这让我迷惑,百度上根本就没有人说清楚
今天,通过研究和朋友的讨论,终于是找到了答案,至于答案是什么,请耐心往下阅读~
问题出现
测试的图片地址为http://www.xbiquge.la/files/article/image/10/10489/10489s.jpg
下载图片代码Java版:
URL url = new URL("http://www.xbiquge.la/files/article/image/10/10489/10489s.jpg");
URLConnection connection=url.openConnection();//打开链接
InputStream inputStream = connection.getInputStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File("e:\\test.jpg")));
int c;
byte[] temp = new byte[1024 * 2];//提供个缓冲区
while ((c = bufferedInputStream.read(temp)) != -1) {
bufferedOutputStream.write(temp,0,c);//读多少,写多少
}
bufferedOutputStream.close();
inputStream.close();
下载代码Kotlin版:
val file =File("e:\\test.jpg")
val openConnection = URL("http://www.xbiquge.la/files/article/image/10/10489/10489s.jpg").openConnection()
val bytes = openConnection.getInputStream().readBytes()
file.writeBytes(bytes)
我们通过上面的对比,明显可以看到Kotlin的代码比Java的要简洁不少
上面的代码都是没错,把图片下载下来,打开如下图显示
之后用浏览器打开,用另存为保存图片,图片是可以正常打开的
用迅雷测试,也是打不开,问题似乎找不到原因了
不甘心认输的我,去搜索了一下,添加了各种请求头,但还是无效,似乎到了死胡同了
原因
没办法,只好去向学习群里的大佬们请教了
“哎,这个图片还可以解压,里面有图片!”群里名为夜深的网友说道。
?!我将图片的扩展名改为了zip,之后解压,果不其然发现了可以正常打开的图片
我们知道了下载下来的文件是个压缩包,这样问题也是得到了解决方法,但是,为什么会这样呢?
刚好和python的大佬聊到了这个问题,他试了一下,python可以正确获得到图片,为什么java就不行?经过讨论,从请求头发现了原因,如下图
原来是因为网站在响应的时候返回的是GZIP压缩过的文件流,而采用此方式的话可以减少用户浏览网页的等待时间
python和浏览器都是内置了自动解压缩的功能,所以,这就是为什么浏览器可以查看图片,python也可以得到正确图片的原因
解决方法
针对gzip文件流
这里我们只需要使用GZIPInputStream
包装一下InputStream,之后再输出即可,这里我只贴kotlin版的代码,Java的话参考一下来改吧
val file =File("e:\\test.jpg")
val openConnection = URL("http://www.xbiquge.la/files/article/image/10/10489/10489s.jpg").openConnection()
val bytes = GZIPInputStream(openConnection.getInputStream()).readBytes()
file.writeBytes(bytes)
通用下载图片方法
由于我们所要下载的图片,可能服务器返回的是未压缩的图片,如果我们继续使用上面的方法就会报错
所以我们需要加个判断,判断输入流是否为压缩过的
这里我就直接封装成一个方法了
fun downloadImage(url: String, file: File): File {
val openConnection = URL(url).openConnection()
//防止某些网站跳转到验证界面
openConnection.addRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36")
//如果图片是采用gzip压缩
val bytes = if (openConnection.contentEncoding == "gzip") {
GZIPInputStream(openConnection.getInputStream()).readBytes()
} else {
openConnection.getInputStream().readBytes()
}
file.writeBytes(bytes)
return file
}
参考
How to check if InputStream is Gzipped? stackflow
原文链接:https://www.cnblogs.com/stars-one/p/12358486.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash