java中怎么下载图片不显示图片_关于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的要简洁不少

上面的代码都是没错,把图片下载下来,打开如下图显示

aa266c4d8ecd25fde1bbd63ab5be9e9c.png

之后用浏览器打开,用另存为保存图片,图片是可以正常打开的

用迅雷测试,也是打不开,问题似乎找不到原因了

不甘心认输的我,去搜索了一下,添加了各种请求头,但还是无效,似乎到了死胡同了

原因

没办法,只好去向学习群里的大佬们请教了

“哎,这个图片还可以解压,里面有图片!”群里名为夜雨的网友说道。

?!我将图片的扩展名改为了zip,之后解压,果不其然发现了可以正常打开的图片

0d75395cbd824a7ff223fa8b42a4267a.png

我们知道了下载下来的文件是个压缩包,这样问题也是得到了解决方法,但是,为什么会这样呢?

刚好和python的大佬聊到了这个问题,他试了一下,python可以正确获得到图片,为什么java就不行?经过讨论,从请求头发现了原因,如下图

039c970778373637b92989b547859bd8.png

原来是因为网站在响应的时候返回的是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

}

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值