简体   繁体   English

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

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

I can "fix" the below exception with a try-catch loop but I cannot understand the reason. 我可以使用try-catch循环“修复”以下异常,但我无法理解原因。

  1. Why does the part "in.readLine()" continuosly ignite IOExceptions? 为什么“ in.readLine()”部分会持续点燃IOExceptions?
  2. What is really the purpose of throwing such exceptions, the goal probably not just more side effects? 抛出此类异常的真正目的是什么,目标可能不只是更多的副作用?

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

The basic idea is that a BufferedReader delegates to a different kind of Reader, so it is passing on that exception. 基本思想是BufferedReader委托给另一种类型的Reader,因此它正在传递该异常。

That different kind of Reader can read from some kind of volatile external resource, say a file system in the case of FileReader. 那种不同类型的Reader可以从某种易失的外部资源中读取,例如FileReader的文件系统。 A file system read can fail for many reasons at any time. 文件系统读取可能随时因多种原因而失败。 (The situation is worse if the Reader is getting its underlying data from a Network Stream). (如果Reader从网络流中获取其基础数据,情况将更糟)。 The file could get deleted out from under you (depending on the file system and OS involved). 该文件可能会从您下方删除(取决于所涉及的文件系统和操作系统)。

Because you cannot predict what will happen with code, you get a checked exception - the point being that the API is telling you that you should think about the fact that this operation may not work out even if there is nothing wrong with your code. 因为您无法预测代码会发生什么,所以会得到一个检查过的异常-关键是API告诉您应该考虑以下事实:即使您的代码没有问题,此操作也可能无法执行。

  1. It won't "continously ignite" them, it just might throw them each time you invoke it. 它不会“汽车无点燃”他们, 也许会在每次调用它的时候把他们。 In your case, if it throws something it means something has gone badly wrong with your standard input. 在您的情况下,如果它抛出了某些东西,则意味着您的标准输入出现了严重错误。
  2. The goal is to ensure that you, the programmer using the API, deals with the problem, since it is in general assumed to be a recoverable problem - although in your particular case it will be fatal for your whole program. 目的是确保您(使用API​​的程序员)能够解决该问题,因为一般认为它是可恢复的问题-尽管在您的特定情况下,这对整个程序来说是致命的。

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

You either need to catch it, or declare your main method as throwing IOException. 您要么需要捕获它,要么将您的主要方法声明为抛出IOException。

Ie, either do this: 即,要么这样做:

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

Or 要么

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

IOException is a checked exception . IOException是一个检查的异常 You must either catch it, or throw it to your calling method. 您必须捕获它,或将其扔到调用方法中。 Checked exceptions are caused by external actors, like a missing file, failed disk or anything that you cannot recover from in your program code. 受检查的异常是由外部参与者造成的,例如文件丢失,磁盘故障或无法从程序代码中恢复的任何内容。

However an Unchecked exception like ArrayIndexOutofBoundsException is caused by faulty logic in the program. 但是,诸如ArrayIndexOutofBoundsException之类的Unchecked异常是由程序中的错误逻辑引起的。 You can subvert it by using an if condition outside your defective code (something like if currIndex>array.length). 您可以通过在有缺陷的代码之外使用if条件来破坏它(类似于currIndex> array.length)。 There is no such provision in case of checked exception 如果有检查异常,则没有这样的规定

It is thrown if an exceptional situation occurs with the I/O, for example the source of the stream is no longer available. 如果I / O发生异常情况,则会抛出该异常,例如,流的源不再可用。

In such cases your program should be able to recover. 在这种情况下,您的程序应该可以恢复。 Either by re-reading the source, or by using some defaults, or by alerting the user about the problem. 通过重新阅读源代码,或者使用某些默认值,或者通过警告用户有关问题的方式。

You are forced to catch it, because it is a checked exception, and you are supposed to be able to recover from those. 您被迫catch它,因为它是一个已检查的异常,并且您应该能够从中恢复。

Of course, you have the option to declare that the current menthod throws this exception to caller methods, but you will have to catch it eventually (or let it bubble up to the main method, when it is simply printed on the console and the program execution stops) 当然,您可以选择声明当前方法throws异常throws给调用方方法,但是最终您必须捕获它(或者将其简单地打印在控制台和程序上,使其冒泡至main方法。执行停止)

Using Scanner for reading files (or other type of input) can be extremely inefficient in mid/large scale situations. 在中/大型情况下,使用Scanner读取文件(或其他类型的输入)可能效率极低。 If you have performance concerns reading thousands or milions of lines, i strongly recommend you use BufferedReader class instead. 如果您对读取成千上万的行有性能问题,我强烈建议您改用BufferedReader类。 An example of usage of BufferedReader to read lines from System.in is displayed below: 下面显示了使用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 should be used in try/catch block so can be triggered whenever the protected code inside try suffers of an "exceptional" behavior such as an error. IOException应该在try/catch块中使用,因此只要try受保护代码遭受“异常”行为(例如错误),就可以触发IOException。 Java has his own Exceptions that are throwned when similar situation happen. Java有他自己的异常,当发生类似情况时会抛出该异常。 For example, ArrayIndexOutOfBoundsException is throwned when you define an array a of size n and you try to access the position a[n+1] somewhere in your code. 例如,当您定义大小为n的数组a并尝试访问代码中某处的位置a[n+1]时,将引发ArrayIndexOutOfBoundsException As ArrayIndexOutOfBoundsException , there are many other Exception classes you can throw and customize with your own messages. 作为ArrayIndexOutOfBoundsException ,您可以抛出许多其他Exception类,并使用自己的消息进行自定义。 The code suitable to an exception should be placed in the protected zone in try block. 适用于异常的代码应放在try块的受保护区域中。 When the exception occurs in that block, the exception will be handled in catch block with it. 当该块中发生异常时,将在catch块中处理该异常。

Look that you don't need to build if/else statements to anticipate the error situation and throw an Exception for each case. 看起来您不需要构建if/else语句来预期错误情况并为每种情况引发Exception。 You just need to associate possible Exception situations between try and catch block. 您只需要在trycatch块之间关联可能的异常情况。 See more about try/catch blocks is encouraged for safe programming. 为了安全编程,鼓励查看更多关于try / catch块的信息

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

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