【问题标题】:How to properly catch exceptions with java file I/O [duplicate]如何使用 java 文件 I/O 正确捕获异常 [重复]
【发布时间】:2018-02-04 15:52:52
【问题描述】:

我正在尝试熟悉 Java 中的文件 I/O。我一开始在编译时遇到了很多错误,例如error: unreported exception IOException; must be caught or declared to be thrown。所以我对代码做了一些修改,最终得到:

public static void main(String[] args){
    FileInputStream in = null;
    FileOutputStream out = null;
    String content = "hello";
    byte[] contentBytes = content.getBytes();

    try{
        out = new FileOutputStream("output.txt");
        out.write(contentBytes);
    }catch(IOException e){

    }catch(FileNotFoundException e){

    }
    finally{
        if (out != null)
            out.close();
    }
}

不过,我得到了这个错误:

FileIO.java:16: error: exception FileNotFoundException has already been caught
        }catch(FileNotFoundException e){
         ^
FileIO.java:21: error: unreported exception IOException; must be caught or declared to be thrown
                out.close();
                         ^
2 errors
  1. 我在哪里“已经抓住”FileNotFoundException
  2. 由于第二个错误,是否需要在finally子句中再添加一个trycatch语句来捕获IOException?这看起来很混乱而且过于复杂。我做错了什么吗?为什么 java 不让我做我想做的事而不强迫我捕获异常?

编辑:

如果我这样做:

public static void main(String[] args){
    FileOutputStream out = null;
    String content = "hello";
    byte[] contentBytes = content.getBytes();

    try{
        out = new FileOutputStream("output.txt");
        out.write(contentBytes);
    }catch(FileNotFoundException e){

    }catch(IOException e){

    }
    finally{
            if (out != null)
            out.close();

    }
}

我明白了:

FileIO.java:20: error: unreported exception IOException; must be caught or declared to be thrown
                out.close();
                         ^
1 error

【问题讨论】:

  • 您的其他问题可能在这里得到解答:Java catching exceptions and subclases。虽然我建议坚持每个帖子一个问题,以便为每个问题获得更好的答案,并使帖子对其他人更有用。
  • @Ravi 该帖子目前提出了两个不同的问题 - 可能需要对问题主体进行相当重要的编辑(作者)以证明仅关注其中一个的标题(尽管答案会使这样的编辑有问题)。
  • @Dukeling 你是在建议我回滚吗?
  • @Ravi 差不多,如果你愿意的话。虽然我不太介意,因为我认为这个问题应该被关闭,因为它过于宽泛或重复。
  • @Dukeling 我回滚到旧更改。我想使标题更有意义,以便人们可以轻松搜索。但是,我同意你的观点。 :-)

标签: java


【解决方案1】:

我在哪里“已经捕获”了 FileNotFoundException?

FileNotFoundException 扩展了IOException,这意味着IOException 可以捕获FileNotFoundException 异常。所以,后面没有FileNotFoundException

只需颠倒顺序,即可解决此问题。

}catch(FileNotFoundException e){

}catch(IOException e){

}

另外,不要将 catch 块留空,使用它们来显示适当的消息,否则如果出现异常,您将没有任何线索。

第二个错误,是否需要在 finally 子句中添加另一个 try 和 catch 语句来捕获 IOException?

是的。但是,我建议使用try-with-resource,它会在最后关闭资源。


如前所述,您应该改用try-with-resource

try (FileOutputStream out = new FileOutputStream("people.bin");) 
{
   out.write(contentBytes);
}
catch(FileNotFoundException e)
{

}catch(IOException e){

}

【讨论】:

  • 谢谢。问题二呢?
  • @Sahand 已经回答了。如果您有任何具体问题,请告诉我。
  • 不是,同样的错误仍然存​​在于您的解决方案中。
  • @Sahand 我已经多次注意到,您似乎有立即投票的习惯。你应该有耐心,来回提问。
  • @Sahand 是的。它只负责关闭资源,否则它与旧版本相同
【解决方案2】:

我不太确定编译器是如何让您编写代码的。你能试试下面的代码吗?我运行它时没有任何错误。

第一个问题的答案是:

要么删除 FileNotFoundException 行,要么将其放在 IOexception 之上。

第二个问题的答案是:

如果您认为这很混乱,您可以使用 Throws 来避免异常,即在 main(String[] args) 旁边抛出 IOException。

Java(编译器)促使您捕获或声明您的异常(使用 throws),因为 Java 中异常的主要目的不是在代码运行时遇到错误。当 finally 块中发生异常时,它会导致错误并最终在运行时影响您的应用程序。在 finally 块中关闭内容时必须非常小心。如果您认为代码看起来很乱,那么您可以使用 Throws 关键字来解决您的问题。

    public static void main(String[] args){
        FileInputStream in = null;
        FileOutputStream out = null;
        String content = "hello";
        byte[] contentBytes = content.getBytes();

        try{
            out = new FileOutputStream("output.txt");
            out.write(contentBytes);
        }catch(IOException e){

        }
        finally{
            if (out != null){
    try{
                out.close();
    }catch(IOException e){

    }
    }
        }
    }

【讨论】:

  • 它有效。但是为什么我们需要这么多尝试和捕获呢?
  • 嗨@Sahand,我已根据您的要求更新了帖子。请通过它。感谢您的投票。快乐编码!
  • 谢谢。不过似乎有格式错误。
  • 嗨,哪一行?
  • 在答案本身中。
【解决方案3】:
String outputPath = "output.txt";
String content = "hello";
byte[] contentBytes = content.getBytes();
try (FileOutputStream out = new FileOutputStream(outputPath)) {
    out.write(contentBytes);
} catch (FileNotFoundException e) {
    System.err.println("Failed to find the file to write to: " + outputPath);
} catch (IOException e) {
    System.err.println("Failed to write to file: " + outputPath);
}

正如 QuakeCore 提到的 FileNotFoundEception 扩展 IOException,这就是为什么你应该首先捕获 FileNotFoundEception。

最好打印至少一些消息,这样当控制台/日志中没有输出且没有异常时,您不会感到惊讶。

FileOutputStream 实现 AutoClosable 接口。这就是为什么最好使用try with resources。在这种情况下,JVM 会自动关闭它。

【讨论】:

    【解决方案4】:
    public static void main(String[] args) throws IOException{
    FileOutputStream out = null;
    String content = "hello";
    byte[] contentBytes = content.getBytes();
    
    try{
        out = new FileOutputStream("output.txt");
        out.write(contentBytes);
    }catch(FileNotFoundException e){
    
    }
    finally{
            if (out != null)
            out.close();
    
    }
    

    }

    【讨论】:

    • FileNotFoundException 自己捕获 IOException 有什么意义?
    • 异常可以是ioexception或filenotfoundexception,在这两种情况下catch子句都会捕获它
    【解决方案5】:

    由于FileNotFoundException 扩展了IOException,那么只需捕获IOException,您就可以捕获IOException 的所有子类型。

    And regarding your second question, since `.close()` method also throws `IOException`, you can put all the IO code in a method, and have that method to throw `IOException`, then the caller can deal with the any exceptions.
    
    for example:
    
    private static void writeToFile() throws IOException{
     FileInputStream in = null;
        FileOutputStream out = null;
        String content = "hello";
        byte[] contentBytes = content.getBytes();
        try{
            out = new FileOutputStream("output.txt");
            out.write(contentBytes);
        }finally{
            if (out != null)
                out.close();
        }
    }
    

    然后你的 main 看起来像这样。

    public static void main(String[] args){
        FileInputStream in = null;
        FileOutputStream out = null;
        String content = "hello";
        byte[] contentBytes = content.getBytes();
    
        try{
           writeToFile();
        }catch(IOException e){
    
        }
    }
    

    看看tryResourceClose

    【讨论】:

    • 谢谢。第二题呢?
    猜你喜欢
    • 2013-10-03
    • 2017-11-14
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多