Java:BufferedReader 的 readLine() 中的 IOEXceptions 有什么用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2629649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: what are IOEXceptions in BufferedReader's readLine() for?
提问by hhh
I can "fix" the below exception with a try-catch loop but I cannot understand the reason.
我可以使用 try-catch 循环“修复”以下异常,但我无法理解原因。
- Why does the part "in.readLine()" continuosly ignite IOExceptions?
- What is really the purpose of throwing such exceptions, the goal probably not just more side effects?
- 为什么“in.readLine()”部分会持续引发 IOExceptions?
- 抛出这种异常的真正目的是什么,目标可能不仅仅是更多的副作用?
Code and IOExceptions
代码和 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);
}
}
}
采纳答案by Yishai
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. 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). The file could get deleted out from under you (depending on the file system and OS involved).
那种不同类型的 Reader 可以从某种易变的外部资源中读取,比如 FileReader 中的文件系统。文件系统读取在任何时候都可能因多种原因而失败。(如果 Reader 从网络流获取其底层数据,情况会更糟)。该文件可能会从您的下方删除(取决于所涉及的文件系统和操作系统)。
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 告诉您,您应该考虑这样一个事实,即使您的代码没有任何问题,此操作也可能无法执行。
回答by Midhat
IOException is a checked exception. 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.
IOException 是一个检查异常。您必须捕获它,或者将它扔给您的调用方法。检查异常是由外部参与者引起的,例如丢失的文件、失败的磁盘或您无法从程序代码中恢复的任何内容。
However an Unchecked exception like ArrayIndexOutofBoundsException is caused by faulty logic in the program. You can subvert it by using an if condition outside your defective code (something like if currIndex>array.length). There is no such provision in case of checked exception
然而,像 ArrayIndexOutofBoundsException 这样的 Unchecked 异常是由程序中的错误逻辑引起的。您可以通过在有缺陷的代码之外使用 if 条件来颠覆它(类似于 if currIndex>array.length)。在检查异常的情况下没有这样的规定
回答by Bozho
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
这个异常传递给调用者方法,但是您最终必须捕获它(或者让它冒泡到主方法,当它简单地打印在控制台和程序执行时停止)
回答by Tom Jefferys
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/en/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.
您要么需要捕获它,要么将 main 方法声明为抛出 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 { ...
回答by jjujuma
- It won't "continously ignite" them, it just mightthrow them each time you invoke it. In your case, if it throws something it means something has gone badly wrong with your standard input.
- 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 的程序员)处理该问题,因为它通常被认为是一个可恢复的问题 - 尽管在您的特定情况下这对您的整个程序来说是致命的。
回答by Carlos Sá
Using Scanner
for reading files (or other type of input) can be extremely inefficient in mid/large scale situations. If you have performance concerns reading thousands or milions of lines, i strongly recommend you use BufferedReaderclass instead. An example of usage of BufferedReader to read lines from System.in
is displayed below:
使用Scanner
用于读取文件(或其他类型的输入)可以是在中/大型的情况下效率极低。如果您对读取数千或数百万行的性能有顾虑,我强烈建议您改用BufferedReader类。System.in
下面显示了使用 BufferedReader 读取行的示例:
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. Java has his own Exceptions that are throwned when similar situation happen. 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.
As ArrayIndexOutOfBoundsException
, there are many other Exception classes you can throw and customize with your own messages.
The code suitable to an exception should be placed in the protected zone in try block. When the exception occurs in that block, the exception will be handled in catch block with it.
IOException 应该在try/catch
块中使用,因此可以在内部try
受保护的代码遇到“异常”行为(例如错误)时触发。Java 有自己的异常,在类似情况发生时会抛出这些异常。例如,ArrayIndexOutOfBoundsException
当您定义一个a
大小的数组n
并尝试访问a[n+1]
代码中某处的位置时抛出。因为ArrayIndexOutOfBoundsException
,还有许多其他 Exception 类,您可以使用自己的消息抛出和自定义。适合异常的代码应该放在 try 块中的受保护区域。当该块中发生异常时,异常将在 catch 块中处理。
Look that you don't need to build if/else
statements to anticipate the error situation and throw an Exception for each case. You just need to associate possible Exception situations between try
and catch
block. See more about try/catch blocksis encouraged for safe programming.
看起来您不需要构建if/else
语句来预测错误情况并为每种情况抛出异常。您只需要在try
和catch
块之间关联可能的异常情况。为了安全编程,鼓励查看更多关于try/catch 块的信息。