繁体   English   中英

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

[英]Java: what are IOEXceptions in BufferedReader's readLine() for?

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

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

代码和IOException

$ 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,因此它正在传递该异常。

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

因为您无法预测代码会发生什么,所以会得到一个检查过的异常-关键是API告诉您应该考虑以下事实:即使您的代码没有问题,此操作也可能无法执行。

  1. 它不会“汽车无点燃”他们, 也许会在每次调用它的时候把他们。 在您的情况下,如果它抛出了某些东西,则意味着您的标准输入出现了严重错误。
  2. 目的是确保您(使用API​​的程序员)能够解决该问题,因为一般认为它是可恢复的问题-尽管在您的特定情况下,这对整个程序来说是致命的。

BufferedReader.readLine()被声明为可能引发异常,请参见: https : //docs.oracle.com/zh-CN/java/javase/11/docs/api/java.base/java/io/BufferedReader.html#readLine ()

您要么需要捕获它,要么将您的主要方法声明为抛出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是一个检查的异常 您必须捕获它,或将其扔到调用方法中。 受检查的异常是由外部参与者造成的,例如文件丢失,磁盘故障或无法从程序代码中恢复的任何内容。

但是,诸如ArrayIndexOutofBoundsException之类的Unchecked异常是由程序中的错误逻辑引起的。 您可以通过在有缺陷的代码之外使用if条件来破坏它(类似于currIndex> array.length)。 如果有检查异常,则没有这样的规定

如果I / O发生异常情况,则会抛出该异常,例如,流的源不再可用。

在这种情况下,您的程序应该可以恢复。 通过重新阅读源代码,或者使用某些默认值,或者通过警告用户有关问题的方式。

您被迫catch它,因为它是一个已检查的异常,并且您应该能够从中恢复。

当然,您可以选择声明当前方法throws异常throws给调用方方法,但是最终您必须捕获它(或者将其简单地打印在控制台和程序上,使其冒泡至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受保护代码遭受“异常”行为(例如错误),就可以触发IOException。 Java有他自己的异常,当发生类似情况时会抛出该异常。 例如,当您定义大小为n的数组a并尝试访问代码中某处的位置a[n+1]时,将引发ArrayIndexOutOfBoundsException 作为ArrayIndexOutOfBoundsException ,您可以抛出许多其他Exception类,并使用自己的消息进行自定义。 适用于异常的代码应放在try块的受保护区域中。 当该块中发生异常时,将在catch块中处理该异常。

看起来您不需要构建if/else语句来预期错误情况并为每种情况引发Exception。 您只需要在trycatch块之间关联可能的异常情况。 为了安全编程,鼓励查看更多关于try / catch块的信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM