Java使用BufferedReader读取URL内容时遭遇Premature EOF异常求助
解决读取URL内容时的Premature EOF异常
你遇到的这个Premature EOF异常,从堆栈跟踪里的ChunkedInputStream就能定位到核心问题:这是HTTP分块传输编码(Chunked Transfer Encoding)的处理异常。当服务器用分块方式返回数据时,旧版的HttpURLConnection在读取流时如果遇到分块标记异常、连接中断或者未处理压缩编码,就会触发这个错误。以下是几个可行的解决方案:
1. 使用Java 11+的HttpClient(最推荐)
Java 11引入的HttpClient是替代老旧HttpURLConnection的现代方案,它对HTTP分块传输、压缩、超时等场景的处理更完善,代码也更简洁:
import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; public class UrlReader { public static void main(String[] args) { String url = "你的目标URL"; HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .timeout(Duration.ofSeconds(10)) // 设置超时时间,避免无限等待 .build(); try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); String result = response.body(); System.out.println("读取到的内容长度:" + result.length()); } catch (Exception e) { e.printStackTrace(); } } }
2. 修复HttpURLConnection的读取逻辑
如果必须使用HttpURLConnection,需要补充超时设置、处理压缩编码,并用try-with-resources自动管理资源(避免手动关闭时的遗漏):
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.zip.GZIPInputStream; public class OldUrlReader { public static void main(String[] args) { String url = "你的目标URL"; try (URL targetUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection()) { // 配置连接属性 connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); // 连接超时5秒 connection.setReadTimeout(10000); // 读取超时10秒 connection.setRequestProperty("Accept-Encoding", "gzip, deflate"); // 接受压缩编码 connection.setInstanceFollowRedirects(true); // 自动处理重定向 // 处理压缩流 InputStream inputStream = connection.getInputStream(); String encoding = connection.getContentEncoding(); if (encoding != null && encoding.equalsIgnoreCase("gzip")) { inputStream = new GZIPInputStream(inputStream); } // 读取内容 StringBuilder result = new StringBuilder(); try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { String line; while ((line = br.readLine()) != null) { result.append(line); } } System.out.println("读取到的内容长度:" + result.length()); } catch (Exception e) { e.printStackTrace(); } } }
为什么之前的代码会出错?
你之前的两种实现都直接使用URL.openStream(),这是HttpURLConnection的简化用法,缺少了关键的配置:
- 没有设置超时时间,若服务器响应缓慢或中断,容易触发异常
- 未处理服务器返回的压缩编码(比如gzip),导致流读取不完整
- 手动关闭资源的逻辑可能存在遗漏,引发流状态异常
内容的提问来源于stack exchange,提问作者Void
相关产品推荐
相关产品推荐

