java - java.io.EOFException:读取流数据期间 ZLIB 输入流意外结束
问题描述
下面的代码用于从 API 读取数据。来自 API 的数据流采用 gzip 编码。当单个 API 被命中时,数据会正确出现,但是当使用多线程同时命中几个 API(不同的)时,它会在下面的代码中的reader.readLine()行中抛出异常。
使用的JDK:1.8
例外:
java.io.EOFException:java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240) 处的 ZLIB 输入流意外结束 ~[?:1.8.0_191]
url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
if (urlConnection != null) {
//encoding
urlConnection.setConnectTimeout(5000);
urlConnection.setReadTimeout(0);
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Authorization", "Basic " + encoded);
urlConnection.setRequestProperty("Accept-Encoding", "gzip");
urlResponseCode = urlConnection.getResponseCode();
if (urlResponseCode == HttpURLConnection.HTTP_OK) {
inputStream = urlConnection.getInputStream();
if (inputStream != null) {
if ("gzip".equalsIgnoreCase(urlConnection.getContentEncoding())) {
reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(inputStream)));
} else {
reader = new BufferedReader(new InputStreamReader(inputStream));
}
String line;
long mb = 1024 * 1024;
while ((line = reader.readLine()) != null) {
//adding the line to a String Builder
}
我知道有一些基于此异常的 stackoverflow 文章,但这些文章的情况不同。所以,我问了这个。
我也知道异常可以被捕获并向前推进。但这可能会导致数据丢失。因此,最好提供替代方法。
此异常的原因可能是什么?
解决方案
我也知道异常可以被捕获并向前推进。但这可能会导致数据丢失。因此,最好提供替代方法。
除非我弄错了,否则您在客户端无能为力。
问题是您的客户端代码正在读取的输入流已被截断。
它可能是:
- 服务器中的应用程序代码未正确关闭生成 gzip 压缩数据的流。这很容易导致最后一个块没有被压缩和写入。(A
flush()
是不够的。它GZIPOutputStream
本身必须关闭......假设这是生成压缩数据流的方式。) - 服务器在响应中设置了不正确的内容长度,导致客户端 HTTP 堆栈截断流。
服务器也可能“放弃”请求,因为客户端读取它的速度太慢,或者遇到了错误。这些事情中的任何一个都可能是由于客户端(或多个客户端)的请求使服务器过载。但如果是这样,解决方案仍然必须在服务器端;例如,减少服务器端工作线程的数量,以便服务器更好地处理过载。
推荐阅读
- android - Cordova 应用程序无法在模拟器中启动
- python - 使用函数作为参数
- javascript - 为什么我的变量没有在错误处理功能中更新?
- docker - docker 容器运行镜像busybox的包管理器:uclibc
- c# - Bouncycastle 解密 PKCS8
- c# - 泛化一个泛型类
- jenkins - 如何在作业开始前执行脚本?
- docker - 无法在 WSL 上从 Ubuntu 卸载 Docker
- python-3.x - 用于无边界表格提取的 Tabula-py
- spring-boot - 在 Spring 5 中获取 HTTP 404 Content Not Found 错误,WebTestClient