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

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

  1. 为什么“in.readLine()”部分会连续点燃IOExceptions?
  2. 抛出这些exception的真正目的是什么,目标可能不仅仅是更多的副作用?

代码和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); } } } 

基本思想是BufferedReader委托给不同类型的Reader,因此它传递了该exception。

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

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

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

BufferedReader.readLine()被声明为可能引发exception,请参阅: 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 { ... 

IOException是一个经过检查的exception 。 您必须捕获它,或将其抛给您的调用方法。 已检查的exception是由外部参与者引起的,例如丢失的文件,磁盘故障或您无法在程序代码中恢复的任何内容。

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

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

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

您被迫catch它,因为它是一个经过检查的exception,您应该能够从那些中恢复。

当然,你可以选择声明当前的menthod throws这个exception抛给调用者方法,但你最终必须捕获它(或者让它冒泡到main方法,当它只是打印在控制台和程序上时执行停止)

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

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