try with resources 资源自动关闭时如何处理异常?
How to handle exceptions when a resource closes automatically in try with resources?
据此link,如果source在打开的时候有问题抛出异常,而且也在try括号中,JVM会关闭它。我的问题是现在如何通知用户此资源已关闭并且我们在打开此资源时遇到问题?也就是说,这个异常怎么处理?
即使使用 try-with-resources
,catch
子句仍然有效。
private static void printFile() throws MyCustomException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
} catch (IOException e) {
throw new MyCustomException("There was an error while opening the resource", e);
}
}
似乎微不足道。通常,java 代码在某种 'no user interaction' 环境(服务器等)中是 运行。正确的做法是让异常冒泡 - 你 想要 日常工作在读取数据库的过程中打开相关文件,然后将日志发送到长期存储或其他任何地方它是 完全中止 并在日志文件中写一个注释。通常对于这样的工作,有一些原子功能(在这种情况下,也许每个这样的文件都独立于其他文件,并且可以暂时保留 'broken' 一个,直到服务器管理员可以同时查看它继续处理剩余部分 - 在这种情况下,'do the backup rotation thing on THIS file' 是原子功能):捕获所有异常并编写代码,在作业失败时执行您想要的操作。例如,我的服务器可以直接向管理电话发送通知(通过电报或推送,或使用 slack API,并且有许多服务也可以为您自动执行此操作),如果它很重要,您可以将其写在你的捕获块。
对于用户直接 'triggered' 的代码,比方说一个 'save file' 函数,那么它不是那么多 'the resource is now closed' - 资源不会长期存在(它们不能 -如果您使用 try-with-resources 则不会)。它们要么从一开始就从未打开过(您试图将文件保存到一个不存在的目录中——尝试创建新的 OutputStream 的行为已经失败,它从一开始就从未打开过),或者,也许它确实打开了,但它是一个 U 盘,用户在保存到一半时将其拔出。资源 刚刚关闭 ,实际上,无论 java 你是否 .close()
它或不 - 整根棍子都不见了!!
try-with-resources 的 'safe close' 方面为您做的唯一一件事就是确保您的 Java 进程没有浪费文件句柄。
你处理它的方式几乎与你处理任何东西的方式相同 'unrecoverable'(你不能编写催眠用户将 U 盘插回机器的软件,显然 - 它不能作为结果,像大多数异常一样)问题:你抛出一个解释情况的对话框。
try (OutputStream out = Files.newOutputStream(saveGameFile)) {
boardState.save(out);
} catch (IOException e) {
// show dialog here
}
据此link,如果source在打开的时候有问题抛出异常,而且也在try括号中,JVM会关闭它。我的问题是现在如何通知用户此资源已关闭并且我们在打开此资源时遇到问题?也就是说,这个异常怎么处理?
即使使用 try-with-resources
,catch
子句仍然有效。
private static void printFile() throws MyCustomException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
} catch (IOException e) {
throw new MyCustomException("There was an error while opening the resource", e);
}
}
似乎微不足道。通常,java 代码在某种 'no user interaction' 环境(服务器等)中是 运行。正确的做法是让异常冒泡 - 你 想要 日常工作在读取数据库的过程中打开相关文件,然后将日志发送到长期存储或其他任何地方它是 完全中止 并在日志文件中写一个注释。通常对于这样的工作,有一些原子功能(在这种情况下,也许每个这样的文件都独立于其他文件,并且可以暂时保留 'broken' 一个,直到服务器管理员可以同时查看它继续处理剩余部分 - 在这种情况下,'do the backup rotation thing on THIS file' 是原子功能):捕获所有异常并编写代码,在作业失败时执行您想要的操作。例如,我的服务器可以直接向管理电话发送通知(通过电报或推送,或使用 slack API,并且有许多服务也可以为您自动执行此操作),如果它很重要,您可以将其写在你的捕获块。
对于用户直接 'triggered' 的代码,比方说一个 'save file' 函数,那么它不是那么多 'the resource is now closed' - 资源不会长期存在(它们不能 -如果您使用 try-with-resources 则不会)。它们要么从一开始就从未打开过(您试图将文件保存到一个不存在的目录中——尝试创建新的 OutputStream 的行为已经失败,它从一开始就从未打开过),或者,也许它确实打开了,但它是一个 U 盘,用户在保存到一半时将其拔出。资源 刚刚关闭 ,实际上,无论 java 你是否 .close()
它或不 - 整根棍子都不见了!!
try-with-resources 的 'safe close' 方面为您做的唯一一件事就是确保您的 Java 进程没有浪费文件句柄。
你处理它的方式几乎与你处理任何东西的方式相同 'unrecoverable'(你不能编写催眠用户将 U 盘插回机器的软件,显然 - 它不能作为结果,像大多数异常一样)问题:你抛出一个解释情况的对话框。
try (OutputStream out = Files.newOutputStream(saveGameFile)) {
boardState.save(out);
} catch (IOException e) {
// show dialog here
}