当前位置: 首页 > 知识库问答 >
问题:

为什么我只能先关闭套接字的输出流,然后再关闭输入流?

姚飞昂
2023-03-14

我包一个插座。通过InputStreamReader获取getInputStream(),并包装一个套接字。getOutputStream()由OutputStreamWriter创建。我发现这些流的关闭顺序真的很重要,但我不知道为什么。

如果我先关闭outputStream,然后再关闭inputStream,它可以正常工作:

outputStreamWriter.close();
inputStreamReader.close();

但是,如果我先关闭inputStream,然后再关闭outputStream,它会抛出一个错误:

inputStreamReader.close();
outputStreamWriter.close();

错误是:

java.net.SocketException: Socket closed
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implClose(StreamEncoder.java:316)
    at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:149)
    at java.io.OutputStreamWriter.close(OutputStreamWriter.java:233)
    at http.HTTPServer.start(HTTPServer.java:69)
    at http.HTTPTest.main(HTTPTest.java:10)

另外,我想问我是否还需要调用socket。close()在关闭套接字的输入流和输出流之后?如果我先关闭套接字,我还需要关闭这两个流吗?

共有1个答案

颛孙炜
2023-03-14

从插座。关闭()

关闭此套接字还将关闭套接字的InputStreamOutputStream

从插座。getInputStream()

关闭返回的InputStream将关闭关联的套接字。

从插座。getOutputStream()

关闭返回的OutputStream将关闭相关的套接字。

所以你不能故意或无意地关闭一条流。如果你完成了套接字,那么socket。close()可以。虽然如果您使用的是try-with-resources,那么流可能会自动关闭。取决于你的设计如何编写逻辑。

这里异常的原因是OutputStreamWriter缓冲字节,所以当您关闭()时,它首先写出它的缓冲区(如果缓冲区不是空的)。如果您先关闭写入器,套接字仍然打开,字节将被写入,如果您先关闭读取器,套接字将被关闭,您会得到一个异常。

 类似资料:
  • 问题内容: 有人可以解释一下Java套接字中的以下行为: 总体思路是这样的: 打开套接字,获取I / O流。 写请求,关闭流 读取响应,关闭流 关闭插座。 这是我的问题。 如果我将a 用于输出,然后将其关闭,则它将关闭整个套接字,并且随后的读取操作将失败。 相反,如果我直接使用套接字的方法,它将正确关闭输出流通道,同时使套接字保持活动状态。 为什么关闭对象会使整个插槽都掉下来? 问题答案: 这可能

  • JavaSocket API告诉我,关闭一个套接字也会关闭套接字的和。 Socket API Javadoc和Input/OutputStream API info都没有定义(我还没有找到它)对于或来说,“关机”到底意味着什么,但我一直假设关闭会使它们进入“关机”状态。 然而,在我成功调用客户端套接字的方法(调用返回)之后,如果我调用该套接字的或方法,结果是。 我确信在调用套接字的时,两个流都没有

  • 我想做的是:打开大文件的InputStream,读取10MB的块,上传一个块,读取下一个块。 我为这个任务编写了很好的代码,但问题是ContentResolver返回ParcelFileDescriptor。AutoCloseInputStream作为InputStriam。这个实现打破了InputStream的契约,因为它在first.read()之后自动关闭,所以当我尝试读取下一个块时,我得到

  • 问题内容: 我应该负责关闭(或或什至),还是应该将其留给容器? 问题答案: 您确实不需要这样做。 经验法则:如果您没有使用自己创建/打开它,则不需要自己关闭它。例如,如果它是一个,那么您显然需要自己关闭它。 有些人仍然这样做的原因仅仅是为了确保不再将任何内容写入响应主体。如果发生这种情况,则将日志中导致,但这不会影响客户端,因此客户端仍会获得正确的响应。这也是一种更容易的调试,可以发现请求-响应链

  • 问题内容: 我在try / catch块中有以下代码 我的问题是,当我必须在finally块中关闭这些流时,是否必须关闭所有3个流,或者仅关闭 befferedreader 会关闭所有其他流? 问题答案: 按照惯例,包装流(用于包装现有流)在关闭时会关闭基础流,因此仅在示例中必须关闭。而且,关闭已经关闭的流通常是无害的,因此关闭所有3个流都不会受到伤害。

  • 问题内容: Java中的InputStreams和OutputStreams是否在销毁时关闭()?我完全理解这可能是错误的形式(尤其是在C和C ++世界中),但是我很好奇。 另外,假设我有以下代码: 无名的FileInputStream是否在p.load()之后超出范围,并因此被破坏,就像C ++范围规则一样?我尝试在Google上搜索Java的匿名变量范围,但这并没有达到我的预期。 谢谢。 问题