关于Java/Kotlin下载图片,图片翻开不能显现问题探讨
.NET Core之单元测试(四):Fluent Assertions的使用
图片下载实际上是个很简单的功用,经由过程IO流从在线地点猎取流,以后将流输出到文件即可完成下载功用,然则,近来我发明某个网站中的图片下载胜利,然则翻开倒是没法翻开,这让我疑惑,百度上根本就没有人说清楚
本日,经由过程研讨和朋侪的议论,终因而找到了答案,至于答案是什么,请耐烦往下阅读~
问题涌现
测试的图片地点为
下载图片代码Java版:
URL url = new URL("");
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("").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("").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
}
参考
使用ASP.NET Core构建RESTful API的技术指南