图片下载其实是个很简单的功能,通过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

}

参考

java中怎么下载图片不显示图片_关于Java/Kotlin下载图片,图片打开不能显示问题探究...相关推荐

  1. java中所有函数都是虚函数_关于Java:虚拟函数与纯虚函数之间的区别是什么?...

    本问题已经有最佳答案,请猛点这里访问. Possible Duplicate: C++ Virtual/Pure Virtual Explained 虚函数和纯虚函数有什么区别? CPP中的纯虚函数与 ...

  2. JAVA中为什么要用接口定义编程_【Java公开课|为什么要用Java接口,这些内容你一定要搞清楚】- 环球网校...

    [摘要]作为一门面向对象编程语言,Java吸收了C++语言的优点,也展现了其强大的一面,我们能在各个地方看到其功能强大和简单易用的两个特征,当然,也吸引了很多程序员的注意力,所以就有人想了解Java的 ...

  3. Java main方法_解释Java中的main方法,及其作用_一个java文件中可包含多个main方法

    public static void main(String[] args) {} 或者 public static void main(String args[]) {} main方法是我们学习Ja ...

  4. java中dao和实体类的关系_【JAVA基础】 PO、VO、BO、DTO、POJO、DAO之间的关系详解...

    J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候,三分钟就被人家满口的专业术语喷晕了,PO VO BO DTO POJO DAO,一大堆的就来了 首先声明偶也不是什么高手,以 ...

  5. java中怎么调用邮箱自动回信息_使用java发送短信和邮件

    (1)发送短信 1.1在中国网建SMS上注册一个用户名,并获取短信密钥(非登录密码) 1.2代码 import java.io.IOException; import org.apache.commo ...

  6. 以下关于java中布局管理说法错误的是_对于 Java 中的布局管理器,以下说法中错误的是( )。_2019复习答案_学小易找答案...

    [单选题]下列哪个酶与丙酮酸生成糖无关? [单选题]宋代( )的产地是当时的福建建安. [单选题]建筑平面图中,外部尺寸一般标注( )尺寸. [单选题]MCS - 51 单片机的 CPU 主要的组成部 ...

  7. java中实现接口采用的关键字是_一个Java类实现一个接口使用的是implements关键字。...

    个用务人为是导致的债的行销权可能债权人行使撤. 无关调制信号它与及电方式速率,类实务的新业宽带也是引入方便手段,在网展中络发,想的扩容是理手段. 个接s关标志牌的要求水线设置. 的受定期通信预算资格建 ...

  8. java中的後綴表達式_求Java堆栈,将中缀算术表达式转换成后缀表达式。

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package lab2.lang; import java.util.ArrayList; import java.util.HashMap; impo ...

  9. java中某对象的引用什么意思_在java中,引用对象变量和对象间有什么关系?()

    案例分析一:假定CPU的主频是500MHz.硬盘采用DMA方式进行数据传送,其数据传输率为4MB/s, 每次DMA传输的数据量为8KB, 要求没有任何数据传输被错过. 如果CPU在DMA初始化设置和启 ...

  10. java中两个xml文件内容拼接_比较Java中2个XML文档的最佳方法

    慕丝7291255 听起来像是XMLUnit的工作http://www.xmlunit.org/https://github.com/xmlunit例子:public class SomeTest e ...

最新文章

  1. dex文件结构(三):dex文件差分包分成
  2. java泛型反映调用方法体内类型引用问题
  3. 来自开发者的点赞!网易云信揽获3大技术奖项
  4. 从Loagistic 到 SVM算法
  5. Android五大布局详解
  6. JavaScript中的点击事件
  7. linux的多任务编程-线程池,Linux的多任务编程-线程池
  8. 【SICP练习】142 练习3.77
  9. 数据库系统概论-数据库编程与关系查询处理和查询优化
  10. java链表实现多项式的运算
  11. 怎么使用手机号申请邮箱,注册移动手机邮箱有哪些步骤?
  12. 关于mysql出现java.sql.SQLException错误!
  13. UVALive3713 Astronauts
  14. 有道云脑图 mindmap文件必须会员才能导出
  15. FileNotFoundError: [Errno 2] No such file or directory: ‘./train/hazy/hazy‘
  16. 获取一个网址http://www.veryyx.com/......中的www.veryyx.com
  17. mysql 拼音查询_mysql中文字段转拼音首字母,以及中文拼音模糊查询
  18. android开发——分秒计时器(可 开始/暂停/继续/停止)
  19. java modify的使用方法图解,经过JDT修改(Modify)Java代码的流程步骤
  20. 从for循环理解python中break和continue的作用

热门文章

  1. 【经验分享】让iPad或者手机作为电脑扩展屏幕使用—Splashtop Wired XDisplay(亲测有效且免费)
  2. 单目图像深度估计 - 相对深度篇:Depth in the Wild Size to Depth
  3. linux ora01034 27101,ORA-01034和ORA-27101的解决方法
  4. 成都传智播客就业班简介
  5. B站 孜然尿布 投稿视频目录(持续更新中,可能会延后一两部片,想要最新的视频直接找投稿)
  6. 激光雷达初体验 == 思岚A1M8 + Ubuntu 18.04 + ROS melodic + hector_slam
  7. JavaScript教程_ES6(二)
  8. EverNote试用小结
  9. 同城代驾平台开发,代驾软件搭建方案
  10. SwitchHosts高效切换host -- 让开发,测试,线上环境切换更容易