每次使用后是否应该关闭流?

Max*_*ell 5 java inputstream outputstream objectoutputstream bytearrayinputstream

我目前正在为游戏开发 UDP 服务器。在此服务器中,使用 aByteArrayInputStreamObjectInputStreamevery tick 将序列化字节转换为对象。为流创建一个变量并在程序关闭时关闭它们一次是否更有效?

像这样:

class Main {
private static ByteArrayInputStream byteIn;
private static ObjectInputStream objectIn;

public static void main(String[] args) {
    while(true){
      receive();
    }
    //when program is done call close();
}

 public static void receive(){
     byteIn = new ByteArrayInputStream();
     objectIn = new ObjectInputStream(new BufferedInputStream(byteIn));
      //do something
  }

 public static void close(){
    objectIn.close();
    byteIn.close();
  }
}
Run Code Online (Sandbox Code Playgroud)

或者每次创建和关闭新流是否更有效?

像这样:

class Main {

public static void main(String[] args) {
    while(true){
      receive();
    }
}

 public static void receive(){
    ByteArrayInputStream byteIn = new ByteArrayInputStream();
    ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(byteIn));
    //do something
    objectIn.close();
    byteIn.close();
  }
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 2

如果您打开流,则应该关闭它。问题中的代码不会这样做,它只是放弃以前的流并仅关闭它创建的最后一个流。

目前尚不清楚为什么这些流变量应该是static而不是本地的receive。如果它们是本地的receive,您可以使用try-with-resources来自动清理它们:

public static void receive(){
    try (
        ByteArrayInputStream byteIn = new ByteArrayInputStream();
        ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(byteIn));
    ) {
        //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

当控制权传出时,它们将自动关闭try

如果由于某种原因它们必须成为static类成员,只需关闭并释放您创建的每个成员(但是代码中更容易出现错误,这意味着它的执行路径无法做到这一点)。

// All done
objectIn.close();
objectIn = null;
byteIn.close();
byteIn = null;
Run Code Online (Sandbox Code Playgroud)

旁注:对于这三种流类型,您可能不需要byteIn作为单独的变量。更多内容在这个问题的答案中。