简体   繁体   English

有没有一种干净的方法可以赋予Java对象破坏范围?

[英]Is there a clean way to give Java objects scope with destruction?

Imagine that MyOpenedFile is something wrapping file with opened streams. 想象一下MyOpenedFile是带有打开流的包装文件的东西。 Then suppose this code: 然后假设此代码:

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

Actual method for the question: 问题的实际方法:

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; 
    }
}

Now this is quite messy and especially error-prone (some code in finally block might be very hard to get called in unit tests, for example). 现在,这非常混乱,并且特别容易出错(例如,在单元测试中,finally块中的某些代码可能很难调用)。 For example in C++, destructor would take care of cleanup (either getting called by scoped pointer destructor or directly) and code would be much cleaner. 例如,在C ++中,析构函数将负责清理(通过作用域指针析构函数进行调用或直接进行调用),并且代码将更加整洁。

So, is there better/nicer/cleaner way to wrap above piece of business logic code, so that any exceptions get propagated but both files f1 and f2 get closed (or at least close is attempted on both, even if it fails)? 因此,是否有更好/更干净的方法来包装上面的业务逻辑代码,以便传播任何异常,但关闭文件f1f2 (或者至少尝试关闭两个文件,即使失败也是如此)?

Also answers pointing to any open source libraries such as Apache Commons, providing nice wrappers are welcome. 还提供了指向任何开放源代码库(例如Apache Commons)的答案,并提供了不错的包装器。

A file is a wrapper for a String which contains a file name which may or may not exist. 文件是字符串的包装,字符串包含可能不存在的文件名。 It is stateless so you don't need to close it. 它是无状态的,因此您无需关闭它。

A resource you need to close is FileInputStream or BufferedReader and you can close these implicitly with ARM in Java 7 您需要关闭的资源是FileInputStream或BufferedReader,您可以在Java 7中使用ARM隐式关闭这些资源。

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

}

This will close br whent he block exits. 这将关闭br了when他阻止出口。

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

Take a look at The try-with-resources Statement which will close resources after the try-block ends. 看一下try-with-resources语句 ,它将在try块结束后关闭资源。

The File class you use does not seem to be java.io.File because it does not have any close() method. 您使用的File类似乎不是java.io.File因为它没有任何close()方法。 In that case make sure that your own File class implements Closeable to make it work with ARM. 在这种情况下,请确保您自己的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();
}

You dont need to close Files (which are representations of files on the file system) as mentioned here: 您无需关闭文件(这是文件系统上文件的表示形式),如此处所述:

Do I need to close files I perform File.getName() on? 我需要关闭执行File.getName()的文件吗?

I assume you are asking more about the File Streams/Readers? 我假设您正在询问有关文件流/阅读器的更多信息?

In which case java 7 has a nice new feature: http://www.vineetmanohar.com/2011/03/java-7-try-with-auto-closable-resources/ 在这种情况下,Java 7具有一个不错的新功能: http : //www.vineetmanohar.com/2011/03/java-7-try-with-auto-closable-resources/

If you are working on an older version of java I'd just keep it simple with this: 如果您使用的是Java的旧版本,请使用以下命令简化操作:

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

    // do stuff

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

An option that comes automatically to my head is: Separate the code that handles files, from the code that does any processing. 我自动想到的一个选择是:将处理文件的代码与进行任何处理的代码分开。 In this way you can encapsulate the nasty code that handles does the open, close and exception handling. 这样,您可以封装处理打开,关闭和异常处理的讨厌代码。

The other bit is that the sample you have does a lot of extra, unneeded steps 另一点是您拥有的样本执行了许多额外的不必要步骤

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);
    }
}

You don't need to set the File instances to null. 您无需将File实例设置为null。 If you try to use them, you'll get an exception. 如果尝试使用它们,则会出现异常。

I don wonder what File object you're using. 我不知道您正在使用哪个File对象。 The standard File class in java doesn't have a close() method. Java中的标准File类没有close()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM