在这里提供了一些答案并阅读了一些评论之后,实际上似乎IOException永远不会在文件I / O上关闭。
是否有任何情况下,在Stream / Reader / Writer上调用close会实际抛出IOException?
如果实际抛出异常,应如何处理?
答案 0 :(得分:28)
我发现了两个案例:
这两个示例都依赖于缓冲区中仍有数据时发生的事情。在文件关闭之前关闭刷新缓冲区,因此如果将数据写入文件时出错,则会抛出IOException。
如果您执行以下代码,将其传递给要在网络驱动器上创建的文件的名称,然后在按Enter键之前拔下网络电缆,则会导致程序在关闭时抛出IOException。
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开始,您可以使用try-with-resources来摆脱这种混乱(删除了close()
操作的显式异常生成代码):
private static void process(final File file) {
try (final Writer writer = new FileWriter(file)) {
writer.write('a');
} catch (final IOException e) {
// handle exception
}
}
这将自动神奇地处理close()
中的异常,并在内部执行明确的null
检查。
答案 1 :(得分:17)
当它确实发生时,它应该像任何其他IOException
一样处理,而不是像你经常看到的那样被默默地忽略。我猜这个假设是,既然你已经完成了使用流,那么它是否被正确清理并不重要。
但是,正确清理很重要。如果close()
操作确实引发异常,则可能涉及刷新一些输出,提交某些事务(在数据库连接的情况下,您认为是只读的)等等 - 绝对不应该是忽略。而且,由于这种情况很少见,因此您不会通过中止操作来显着降低应用程序的可靠性。
答案 2 :(得分:14)
对于文件,你可能看不到在close()上经常抛出的IOException,但你肯定会看到非文件I / O,比如关闭网络套接字。
关闭UDP套接字的Java错误的Here's an example最终导致抛出IOException。
答案 3 :(得分:5)
特别是FileInputStream.close
,即使您的硬盘发生火灾也不会抛出。据推测,套接字输入是一样的。对于输出流,您也可能正在刷新。直到最近[见时间戳] BufferedOutputStream
过去,如果flush
投掷,则无法关闭基础流。
(@ MaartenBodewes希望我指出API文档没有指定FileInputStream.close
没有投掷。在发布时,习惯上要忽略提及这与Sun JDK相关的条款(现在称为Oracle JDK和OpenJDK。看来,Android使用过的一个名为Apache Harmony的模糊的前重新实现可能有不同的行为。可能还有其他实现或OpenJDK版本也可能抛出。)
答案 4 :(得分:3)
检查调用close时可能发生的情况,异常隐藏如何影响您以及您可以采取的措施:blog post。