为什么在这种情况下需要捕获 IOException

Why is catch IOException needed in this situation

我看到了这个使用 FileInuputStreamFileOutputStream 的例子:

try (FileInputStream in = new FileInputStream("./TestDir/IOfile.txt");
     FileOutputStream out = new FileOutputStream("./TestDir/IOfile_out.txt")) {

    // Do something...

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

我省略了 // Do something... 的部分,因为即使所有这些操作都消失了,这个问题也会发生。

由于FileInputStreamFileOutputStream的构造函数可能会抛出FileNotFoundException,所以我可以理解为什么要捕获FileNotFoundException

可是抓IOException的依据是什么?好像没有它编译器不会让它工作,我不知道我怎么知道这是需要的。

异常来自 close() 方法,如果您在 FileInputStream/FileOutputStream:

中看到 close() 的方法签名
public void close() throws IOException 

它有一个checked exception IOException的throws子句,所以你需要处理它。 此外,由于您使用的是 try-with-resources 块,因此这并不明显,因为您没有明确关闭它。

try块中打开的资源在退出时通过调用close方法自动关闭,前提是资源实现了接口AutoCloseble,否则你不能在 try-with-resources 中使用它们。

如果您不在 FileInputStream/FileOutputStream 上调用 close()(这是不好的)方法,那么您不需要处理 IOException, 以下将编译正常:

 try {
        FileInputStream in = new FileInputStream("./TestDir/IOfile.txt");
        FileOutputStream out = new FileOutputStream("./TestDir/IOfile_out.txt");

        byte[] buffer = new byte[100];
        // more operations
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

然后如果你正确关闭资源,在finally块中:

 try {
        in = new FileInputStream("./TestDir/IOfile.txt");
        out = new FileOutputStream("./TestDir/IOfile_out.txt");

        byte[] buffer = new byte[100];
        // more operations
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }finally{
        try {
            if(in!=null && out!= null) {
                in.close();
                out.close();
            }
        }catch (IOException io){
            io.printStackTrace();
        }
    }

你需要处理它。

因为你正在捕捉FileNotFoundException并不意味着它不能抛出一个IOException

场景 1:找不到文件 => FileNotFoundException
场景 2:找到文件/操作完成,但关闭失败 => IOException

因为您在以下行被异常终止或抛出后立即使用 try-with-resources statement with the FileInputStream which implements AutoCloseable it will call close