IT教程 ·

关于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的要简约不少

上面的代码都是没错,把图片下载下来,翻开如下图显现
关于Java/Kotlin下载图片,图片翻开不能显现问题探讨 IT教程 第1张

以后用阅读器翻开,用另存为保留图片,图片是能够一般翻开的

用迅雷测试,也是打不开,问题好像找不到缘由了

不甘心认输的我,去搜刮了一下,添加了种种要求头,但照样无效,好像到了死胡同了

缘由

没办法,只好去处进修群里的大佬们请教了

“哎,这个图片还能够解压,内里有图片!”群里名为夜深的网友说道。

?!我将图片的扩展名改为了zip,以后解压,果不其然发明了能够一般翻开的图片

关于Java/Kotlin下载图片,图片翻开不能显现问题探讨 IT教程 第2张

我们知道了下载下来的文件是个紧缩包,如许问题也是获得了解决要领,然则,为何会如许呢?

恰好和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的技术指南

参与评论