此问题已在此处有答案:
Try With Resources vs Try-Catch [duplicate](5个答案)
What's the purpose of try-with-resources statements?(7个回答)
Close a Scanner linked to System.in(5个答案)
2天前关闭。
提问
在Java中关闭“I/O资源”的最好/最安全的方法是什么?
上下文
来自python背景,它使用with
创建一个上下文管理器语句来阅读和写入文件,它确保,如果关闭/清理上下文的资源(技术上这可以是任何东西,但内置在io操作中,例如一旦超出范围,即使是套接字也会关闭)
因此,使用此代码:
file = open('workfile', encoding="utf-8")
read_data = f.read()
file.close()
推荐使用with
语句
with open('workfile', encoding="utf-8") as file:
read_data = file.read()
当我们退出with作用域时(字面意思是,前一个缩进级别),即使发生了错误,文件也将始终关闭
你确定我们能做到吗
try:
file = open('workfile', encoding="utf-8")
read_data = f.read()
except Exception as _:
pass
finally:
file.close()
但是,大多数情况下,上下文管理器更好。一个原因是,简单地说,有些人可能会忘记写下file.close()
,但也简单地更干净和安全。
Java示例代码
现在在java中,什么是推荐的,类似的为什么要处理这个?
以Scanner
为例:
public class App
{
public static void main( String... args )
{
Scanner reader = new Scanner(System.in);
try {
System.out.print(">>> username: ");
if (reader.hasNextLine()) {
String username = reader.nextLine();
System.out.format("Hello %s", username);
}
} catch (Exception error) {
System.out.format("Error while reading scanner %s", error);
} finally {
reader.close();
}
}
}
如你所见,我就是这么处理的,
2条答案
按热度按时间xjreopfe1#
我认为你可以使用
try(...){...}catch{}
语句(try with resource statement)
。例如:
从JDK 1.7开始,
try
后面的()
用于初始化程序结束后必须关闭的一个或多个资源。ubby3x7f2#
好吧,这是一个很老的功能,有很好的文档记录,我只是没有看到它。这个功能被称为The try-with-resources Statement。
我保留@shmily作为公认的答案,因为它是正确的,它回答了问题(也是第一个),我只会在这里添加一点,因为它可能会有所帮助,特别是我会为我的用例添加代码,我需要它。
另外,阅读关于用户“Hovercraft Full Of Eels”关于我的实现的最后一条注解
所以在它的简单形式下,我们可以用它作为
现在,根据www.example.com的文档baeldung.com/java-try-with-resources,它表明你实际上可以在外部声明它,只要是 final。
现在,对于我的特定用例,以及第一次评估,我不建议总是这样(因为,实际上即使在他们的示例中,PrintWriter也可能抛出错误FileNotFoundException),因此如果该错误是预先捕获的或预期的,那么它是有意义的。
如果
reader
来自函数参数,则这尤其有意义。话虽如此,这个特性**非常非常类似于python context manager*,你可以定义/自定义你自己的实现
AutoCloseable
的类。只要它调用
close
,你就可以用它做任何你想做的事情(任何类型的清理,资源关闭,API关闭等等)。我看到的唯一区别(至少从用户的Angular 来看,显然每种语言上的实现可能非常不同)是,要在
java
中启用此功能,您确实需要将其放入try/catch块中,而在python
中,它完全独立于错误捕获场景。为什么这是相关的?
在我看来,将它作为一个try-catch场景似乎限制了你实际上可以使用它做什么,特别是,你想要关闭该资源不是因为引发了错误,而是因为它存在于作用域!,这实际上就是它的工作方式,但它可能会让你认为,它只在引发时关闭。
在下面的例子中,我展示了如何在不需要抛出异常的情况下使用它,但是,老实说,它看起来并不像Python那样明显(这不是世界末日)。
正常自动关闭
但是如果我不想抛出错误呢?,我只想调用一些其他的东西,我想确保在对象关闭时被调用。
这样做,它看起来非常类似于python版本,我不需要捕获(和抛出)任何东西,因为这不是我特定的autoclosable的重点,
很酷的一点是,任何在try-with-resource中发生的未捕获的错误仍然会调用close方法
哪些输出
《Hovercraft Full Of Eels》评论
Java有try-with-resources,这可能是最好的方法,除非在某些情况下,其中一种情况是你正在使用System.in(就像你正在做的那样),并希望避免过早关闭它。一旦关闭,该流将保持关闭状态。
所以,尽管上面的例子,我不认为你应该关闭一个扫描
System.in
的扫描仪(但可能有原因)输出
所以要小心!,我其实很惊讶,因为,在许多许多教程中,他们使用扫描仪从终端读取用户输入,然后显示关闭它,which,不是一个文件,但System.in(对我来说就像
stdin
像在C或Pythonsys.stdin
.相当可怕的教程水平在那里.小心!:D