Java:BufferedReader readLine()中的IO EXceptions是什么?

时间:2010-04-13 12:58:18

标签: java exception ioexception

我可以用try-catch循环“修复”下面的异常,但我无法理解原因。

  1. 为什么“in.readLine()”部分会连续点燃IOExceptions?
  2. 抛出此类异常的目的是什么,目标可能不只是更多的副作用?
  3. 代码和IOExceptions

    $ javac ReadLineTest.java 
    ReadLineTest.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown
      while((s=in.readLine())!=null){
                          ^
    1 error
    $ cat ReadLineTest.java 
    import java.io.*;
    import java.util.*;
    
    public class ReadLineTest {
     public static void main(String[] args) {
      String s;
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      // WHY IOException here?
      while((s=in.readLine())!=null){
       System.out.println(s);
      }
     }
    }
    

6 个答案:

答案 0 :(得分:7)

基本思想是BufferedReader委托给另一种类型的Reader,因此它会传递该异常。

不同类型的Reader可以从某种易失性外部资源中读取,例如FileReader中的文件系统。文件系统读取可能由于多种原因而在任何时候失败。 (如果Reader从网络流获取其基础数据,情况会更糟)。该文件可能会从您下面删除(取决于所涉及的文件系统和操作系统)。

因为您无法预测代码会发生什么,所以您会收到一个检查异常 - 关键是API告诉您,即使您的操作没有任何问题,您也应该考虑这个操作可能无法解决的问题。代码。

答案 1 :(得分:3)

  1. 它不会“不断点燃”它们,每次调用它时它只会 抛出它们。在你的情况下,如果它抛出某些东西,就意味着标准输入出现严重错误。
  2. 目标是确保您(使用API​​的程序员)处理问题,因为它通常被认为是一个可恢复的问题 - 尽管在您的特定情况下,它对您的整个程序将是致命的。

答案 2 :(得分:2)

BufferedReader.readLine()被声明为可能引发异常,请参阅:http://java.sun.com/j2se/1.3/docs/api/java/io/BufferedReader.html#readLine()

您需要捕获它,或者将main方法声明为抛出IOException。

即,要么这样做:

try {
    while((s=in.readLine()) != null){
        System.out.println(s);
     }
} catch(IOException e) {
    // Code to handle the exception.
}

或者

public static void main(String[] args) throws IOException { ...

答案 3 :(得分:1)

IOException是checked exception。你必须要么抓住它,要么把它扔给你的调用方法。已检查的异常是由外部参与者引起的,例如丢失的文件,故障磁盘或您无法在程序代码中恢复的任何内容。

然而,像ArrayIndexOutofBoundsException这样的未经检查的异常是由程序中的错误逻辑引起的。您可以使用缺陷代码之外的if条件(如currIndex> array.length)来破坏它。在检查异常的情况下没有这样的规定

答案 4 :(得分:1)

如果I / O出现异常情况,则抛出此异常,例如,流的源不再可用。

在这种情况下,您的程序应该能够恢复。通过重新读取源,或使用某些默认值,或通过提醒用户有关问题。

你被迫catch它,因为它是一个经过检查的例外,你应该可以从那些中恢复。

当然,您可以选择向调用者方法声明当前的menthod throws此异常,但最终必须捕获它(或者让它冒泡到main方法,当它只是打印在控制台上,程序执行停止)

答案 5 :(得分:1)

使用Scanner来读取文件(或其他类型的输入)在中/大规模情况下效率极低。如果您有阅读数千或数百万行的性能问题,我强烈建议您改用BufferedReader类。使用BufferedReader从System.in读取行的示例如下所示:

public static void main(String[] args) throws Exception {

    String line = null;
    BufferedReader br = new BufferedReader (new InputStreamReader(System.in));

    try {
        /* This is protected code. If an problem occurs here, catch block is triggered */
        while ( (line = br.readLine()) != null ){
            System.out.println(line); 
        }
    }
    catch (IOException e){
        throw new IOException("Problem reading a line",e);
    }
}

IOException应该在try/catch块中使用,因此只要try内的受保护代码遭受诸如错误之类的“异常”行为,就可以触发IOException。当有类似情况发生时,Java有自己的异常。例如,当您定义大小为ArrayIndexOutOfBoundsException的数组a并尝试访问代码中某处的位置n时,a[n+1]会被抛弃。 作为ArrayIndexOutOfBoundsException,您可以使用自己的消息抛出和自定义许多其他异常类。 适用于异常的代码应放在try块的受保护区域中。当该块发生异常时,异常将在catch块中处理。

看看您不需要构建if/else语句来预测错误情况并为每种情况抛出异常。您只需要在trycatch块之间关联可能的异常情况。有关try/catch blocks的更多信息,请参阅安全编程。