为啥在这种情况下需要 catch IOException

Posted

技术标签:

【中文标题】为啥在这种情况下需要 catch IOException【英文标题】:Why is catch IOException needed in this situation为什么在这种情况下需要 catch IOException 【发布时间】:2019-03-27 15:47:19 【问题描述】:

我看到了这个使用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方法被a try-with-resources调用会抛出IOException 你不只是阅读一个文件,你 write() 一个不同的文件。写入可能会导致IOException,也许是在您没有路径上的写入权限的情况下。见JavaDocs:write(...) throws IOException。顺便说一句,@CarlosHeuberger 也是对的。 但是没有必要捕捉FileNotFoundException,因为你已经捕捉到IOException @deHaar 但是这个块中没有写close() 方法。是不是因为我用了try()作为try-with-resource的编码方式,所以隐含了close() 我还没有写任何关于 close 方法的东西......但是它被 try with resources 隐式使用。 【参考方案1】:

异常来自close()方法,如果你在FileInputStream/FileOutputStream中看到close()的方法签名:

public void close() throws IOException 

它有一个用于检查异常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();
        
    

你需要处理它。

【讨论】:

但是这个块中没有写close()方法。是不是因为我用try()作为try-with-resource的编码方式,所以隐含了close() @Code_Control_jxie0755 in try-with-resources 在try块中打开资源,并通过调用close方法自动关闭资源,这样你就不会忘记这样做。当退出try 块时,会自动调用实现AutoCloseble 的对象的close() 方法。【参考方案2】:

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

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

由于您将try-with-resources statement 与实现AutoCloseableFileInputStream 一起使用,它将在以下行终止或被异常抛出后立即调用close

【讨论】:

我明白了。 try-with-resources 语句确实包含一个隐含的close() @Code_Control_jxie0755 就是这样。

以上是关于为啥在这种情况下需要 catch IOException的主要内容,如果未能解决你的问题,请参考以下文章

在这种情况下,为啥在调用 AviFileExit() 之前需要核对 IAviFile 指针?

为啥在这种情况下需要使用 *this 返回对象引用? [复制]

为啥我必须将每个 Thread.sleep() 调用包装在 try/catch 语句中? [复制]

为啥在这种情况下星号位置存在差异,而其他情况则没有?

Java异常处理只有Try-Catch吗?

为啥 selectAnnotation 在这种情况下不起作用?