2

想象一下 MyOpenedFile 是用打开的流包装文件的东西。然后假设这段代码:

// method in an Util class
static void safeClose(MyOpenedFile f) {
  if (f != null) {
    try {
      f.close();
    } catch(IOException ex) { /* add logging or console output */ }
  }
}

问题的实际方法:

void doSomeFileOperation(...) throws IOException, ... {
    MyOpenedFile f1 = null;
    MyOpenedFile f2 = null;
    try {

      /* method's "business logic" code beings */
      f1 = new MyOpenedFile(...);
      //do stuff
      f2 = new MyOpenedFile(...);
      // do stuff
      f1.close(); f1 = null;
      // do stuff with f1 closed
      f2.close(); f2 = null;
      // do stuff with f2 closed
      /* method's "business logic" code ends */

    } finally {
      Util.safeClose(f1); f1 = null;
      Util.safeClose(f2); f2 = null; 
    }
}

现在这很混乱,特别容易出错(例如,finally 块中的某些代码可能很难在单元测试中调用)。例如,在 C++ 中,析构函数会负责清理(由作用域指针析构函数调用或直接调用),代码会更干净。

那么,是否有更好/更好/更清洁的方法来包装上面的业务逻辑代码,以便传播任何异常但两个文件都f1f2关闭(或者至少在两者上都尝试关闭,即使它失败了)?

还可以提供指向任何开源库(例如 Apache Commons)的答案,欢迎提供漂亮的包装器。

4

4 回答 4

4

文件是字符串的包装器,其中包含可能存在或不存在的文件名。它是无状态的,因此您无需关闭它。

您需要关闭的资源是 FileInputStream 或 BufferedReader,您可以在 Java 7 中使用 ARM 隐式关闭这些资源

try(BufferedReader br = new BufferedReader(new FileReader(file))) {

}

br当他阻止退出时,这将关闭。

http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html

于 2012-11-01T10:28:02.277 回答
1

看一下try-with-resources 语句,它将在 try-block 结束后关闭资源。

您使用的File类似乎没有,java.io.File因为它没有任何close()方法。在这种情况下,请确保您自己的File类实现Closeable以使其与 ARM 一起使用。

try (FileInputStream f1 = new FileInputStream("test1.txt");
     FileInputStream f2 = new FileInputStream("test2.txt")) {
    // Some code
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
于 2012-11-01T10:27:48.877 回答
1

您不需要关闭文件(这是文件系统上文件的表示形式),如此处所述:

我是否需要关闭执行 File.getName() 的文件?

我假设您正在询问有关文件流/阅读器的更多信息?

在这种情况下,java 7 有一个不错的新功能: http: //www.vineetmanohar.com/2011/03/java-7-try-with-auto-closable-resources/

如果您正在使用旧版本的 java,我会保持简单:

void doSomeFileOperation(...) throws IOException, ... {
  FileInputStream f1 = null;
  FileInputStream f2 = null;
  try {

    // do stuff

  } finally {
    Util.safeClose(f1); 
    Util.safeClose(f2); 
  }
}
于 2012-11-01T10:28:02.323 回答
0

我脑海中自动出现的一个选项是:将处理文件的代码与进行任何处理的代码分开。通过这种方式,您可以封装处理打开、关闭和异常处理的讨厌代码。

另一点是你的样本做了很多额外的、不需要的步骤

void doSomeFileOperation(...) throws IOException, ... {
    File f1 = null;
    File f2 = null;
    try {
      f1 = new File(...);
      f2 = new File(...);
      // callback to another class / method that does the real work
    } finally {
      Util.safeClose(f1);
      Util.safeClose(f2);
    }
}

您不需要将 File 实例设置为 null。如果你尝试使用它们,你会得到一个例外。

我不知道File您使用的是什么对象。java中的标准File类没有close()方法。

于 2012-11-01T10:25:57.270 回答