【问题标题】:Can I consume an entity response after having it initialized GZIPInputStream?我可以在初始化 GZIPInputStream 后使用实体响应吗?
【发布时间】:2014-02-17 15:55:19
【问题描述】:

我的程序正在读取这个大的 gzip 文件,它运行了一个小时,所以它失败并显示以下堆栈跟踪:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:884)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)
    at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:212)
    at org.apache.http.impl.conn.LoggingSessionInputBuffer.read(LoggingSessionInputBuffer.java:82)
    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:182)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)
    at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:238)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
    at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:116)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at com.trainchaser.feed.connections.StaticConnect.getScheduleFile(StaticConnect.java:116)
    at com.trainchaser.app.App.main(App.java:32)

其中StaticConnect.getScheduleFile(StaticConnect.java:116) 行是下面代码中的while 循环。

我已经阅读了类似的帖子,并且在阅读完 while 循环后我确实关闭了阅读器 (in),但它仍然给我同样的错误。所以我想也许如果我使用它会起作用的实体,就像这样:

    HttpEntity entity=getResponse.getEntity();

    BufferedReader in = new BufferedReader(new InputStreamReader(
                        new GZIPInputStream(entity.getContent())));

   EntityUtils.consumeQuietly(entity);

   try
   {
      while ((content = in.readLine()) != null)
      {...

这行得通吗?我在想,如果我暂时存储 gzip 文件并且没有连续分配连接将有助于防止错误。我会自己测试它,但我目前正在测试关闭防火墙的修复,看看它是否仍然出错。

如果有帮助,我正在使用org.apache.http.HttpEntity

【问题讨论】:

  • 告诉我们您使用的是哪个 http 库怎么样?
  • @StephenC,谢谢,我已经相应地编辑了问题。

标签: java gzip socketexception httpentity


【解决方案1】:

我快速浏览了 Apache 4.x HTTP 库源代码,但没有发现任何会导致此调用的内容:

      consumeQuietly(entity);

失败。但是,consumeQuietly 调用将关闭底层输入流……从您的in 流脚下。如果您继续阅读in,您的代码将获得IOException ...下次它需要填充其缓冲区。

但是,我怀疑这并不能解释您所看到的异常。如果我对BufferedReader 代码的解读是正确的,您会看到IOException("stream closed"),而不是SocketException

不管怎样,在你“消费”实体之后继续使用in似乎是个坏主意。


我可以在初始化BufferedReader 后使用实体响应吗?

这是一个不同的问题。是的,你可以这样做。

问题在于您在使用响应后对阅读器做了什么。如果你做的不是关闭它,你就是在自找麻烦……IMO。


顺便说一下,Apache HTTP 库的源代码和核心 Java IO 类都是免费提供的。了解它们的行为方式的最佳方法是阅读源代码……就像我一样。

【讨论】:

  • 啊,好的,谢谢。看起来 java.net.SocketException 的问题:连接重置在于我如何将数据从文件插入到数据库中。它花了很长时间,所以它最终重置了它。它是通过拥有它来修复的,所以我使用 spring 事务
猜你喜欢
  • 2021-09-27
  • 2021-10-27
  • 1970-01-01
  • 2020-09-17
  • 2018-03-12
  • 2018-09-18
  • 1970-01-01
  • 2019-05-12
  • 2020-04-26
相关资源
最近更新 更多