Does close ever throw an IOException?
在这里提供了一些答案,并阅读了一些评论之后,在实践中,IOException似乎永远不会因为文件I/O而被关闭。
在某些情况下,对流/读卡器/编写器调用Close实际上会引发IOException吗?
如果实际抛出了异常,应该如何处理?
我发现了两个案例:
- 当缓冲区中仍有要刷新的数据时,将丢失网络连接。
- 当缓冲区中仍有要刷新的数据时,让文件系统填充(或达到用户对文件大小的限制)。
这两个例子都依赖于缓冲区中仍然存在数据时发生的事情。close在文件关闭之前刷新缓冲区,因此如果将数据写入文件时出错,它将引发IOException。
如果执行以下代码,将要在网络驱动器上创建的文件名传递给它,然后在按Enter键之前拔下网络电缆,它将导致程序在关闭时引发IOException。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class Test { public static void main(final String[] argv) { final File file; file = new File(argv[0]); process(file); } private static void process(final File file) { Writer writer; writer = null; try { writer = new FileWriter(file); writer.write('a'); } catch(final IOException ex) { System.err.println("error opening file:" + file.getAbsolutePath()); } finally { if(writer != null) { try { try { System.out.println("Please press enter"); System.in.read(); } catch(IOException ex) { System.err.println("error reading from the keyboard"); } writer.close(); } catch(final IOException ex) { System.err.println("See it can be thrown!"); } } } } } |
由于Java 7,您可以使用尝试资源来摆脱这种混乱(删除EDCOX1×0操作的显式异常生成代码):
1 2 3 4 5 6 7 | private static void process(final File file) { try (final Writer writer = new FileWriter(file)) { writer.write('a'); } catch (final IOException e) { // handle exception } } |
这将自动神奇地处理
当它真的发生时,它应该像其他任何
但是,正确地清理是很重要的。如果
对于文件,您可能不会经常看到close()上抛出IOException,但对于非文件I/O(如关闭网络的套接字)您肯定会看到它。
下面是一个Java错误的例子,其中关闭一个UDP套接字最终导致一个IOExt被抛出。
特别是
(@maartenbodewes希望我指出,API文档没有指定EDOCX1[5]不抛出。在发帖时,人们习惯于省略提到这与Sun JDK(现在称为Oracle JDK和OpenJDK)相关的条款。看起来,一个鲜为人知的前重新实现ApacheHarmony,Android过去使用它,可能有不同的行为。其他可能的实现,或者OpenJDK的版本,也可能抛出。)
检查一下当调用close时会发生什么,异常隐藏会如何影响你,以及你能做些什么:博客文章。