图片下载实际上是个很简单的功能,经过IO流从在线地址获取流,以后将流输出到文件便可完成下载功能,可是,最近我发现某个网站中的图片下载成功,可是打开倒是没法打开,这让我迷惑,百度上根本就没有人说清楚java
今天,经过研究和朋友的讨论,终因而找到了答案,至于答案是什么,请耐心往下阅读~python
测试的图片地址为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的要简洁很多测试
上面的代码都是没错,把图片下载下来,打开以下图显示
网站
以后用浏览器打开,用另存为保存图片,图片是能够正常打开的url
用迅雷测试,也是打不开,问题彷佛找不到缘由了3d
不甘心认输的我,去搜索了一下,添加了各类请求头,但仍是无效,彷佛到了死胡同了code
没办法,只好去向学习群里的大佬们请教了
“哎,这个图片还能够解压,里面有图片!”群里名为夜深的网友说道。
?!我将图片的扩展名改成了zip,以后解压,果不其然发现了能够正常打开的图片
咱们知道了下载下来的文件是个压缩包,这样问题也是获得了解决方法,可是,为何会这样呢?
恰好和python的大佬聊到了这个问题,他试了一下,python能够正确得到到图片,为何java就不行?通过讨论,从请求头发现了缘由,以下图
原来是由于网站在响应的时候返回的是GZIP压缩过的文件流,而采用此方式的话能够减小用户浏览网页的等待时间
python和浏览器都是内置了自动解压缩的功能,因此,这就是为何浏览器能够查看图片,python也能够获得正确图片的缘由
这里咱们只须要使用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 }