【问题标题】: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,也许是在您没有路径上的写入权限的情况下。见JavaDocswrite(...) throws IOException。顺便说一句,@CarlosHeuberger 也是对的。
  • 但是没有必要捕捉FileNotFoundException,因为你已经捕捉到IOException
  • @deHaar 但是这个块中没有写close() 方法。是不是因为我用了try(){}作为try-with-resource的编码方式,所以隐含了close()
  • 我还没有写任何关于 close 方法的东西......但是它被 try with resources 隐式使用。

标签: java exception 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 就是这样。
猜你喜欢
  • 2016-08-08
  • 2016-07-17
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
相关资源
最近更新 更多