7
  private val in = new BufferedReader(new InputStreamReader(con.getInputStream()))
  private val out = new PrintWriter(con.getOutputStream(), true)
  try {
    while (true) {
      if (in.readLine() == null)
        throw new IOException("connection reset by peer")
    }
  } catch {
    case e: Exception =>
  } finally {

    // Is this necessary?
    in.close()
    out.close()

    // Close socket
    con.shutdownInput()
    con.shutdownOutput()
    con.close()
  }

如果从套接字的输入或输出流创建任何 IO 流或读取器/写入器,是否需要在套接字关闭之前或之后关闭它们?

4

3 回答 3

6

如果从套接字的输入或输出流创建任何 IO 流或读取器/写入器,是否需要在套接字关闭之前或之后关闭它们?

您应该关闭最外面的OutputStream或者Writer您从套接字输出流创建的。这将刷新流并关闭套接字及其输入流。关闭套接字的任何其他方面,例如它的直接输出流、它的输入流或围绕它的任何东西,或套接字本身,完成了大部分但不是全部:具体来说,在输出流之前关闭输入流在您的示例中,防止输出流被刷新,因此可能会丢失数据。

在收盘前调用shutdownInput()or总是多余的。shutdownOutput()

于 2013-03-14T09:44:25.160 回答
5

套接字 Javadoc

关闭此套接字也会关闭套接字的 InputStream 和 OutputStream。

当然,您的代码显式打开的任何读取器/编写器也应该显式关闭,但就网络资源而言,无论如何都会释放它们。

就操作的顺序而言,适用标准规则:最后打开 -> 先关闭。所以在关闭底层套接字连接之前一定要关闭所有的读者/作者。

于 2013-03-14T09:27:04.093 回答
0

在这种情况下没有必要,但它没有害处。

但是,如果您没有在构造函数中设置“autoFlush”标志,那么如果您在关闭之前PrintWriter没有关闭或刷新 ,则可能不会发送一些数据。(如果您以错误的顺序关闭,您可能会遇到异常!)WriterSocket

对于读者/输入流来说,这不是问题。您已经决定忽略任何缓冲输入。


不存在泄漏资源(文件描述符)的问题。如果 Socket 关闭,则释放所有 I/O 资源。你不需要打电话shutdownInputshutdownOutput要么。关闭Socket将做到这一点。

于 2013-03-14T09:35:36.737 回答