关于 Java 中 System.in 的 read() 方法行为的混淆
Posted
技术标签:
【中文标题】关于 Java 中 System.in 的 read() 方法行为的混淆【英文标题】:confusion about the behavior of the read() method of System.in in Java 【发布时间】:2016-10-11 00:17:38 【问题描述】:我知道 System 类的 System.in 是 InputStream 的具体子类的一个实例,因为 InputStream 的 read() 方法是抽象的,System.in 必须覆盖这个方法。 根据关于 InputStream 的 read() 方法的文档:
public abstract int read() 抛出 IOException
从输入流中读取数据的下一个字节。值字节作为 int 返回,范围为 0 到 255。如果由于到达流的末尾而没有可用的字节,则返回值 -1。此方法会一直阻塞,直到输入数据可用、检测到流结束或引发异常。 子类必须提供此方法的实现。
返回: 数据的下一个字节,如果到达流的末尾,则为 -1。
投掷: IOException - 如果发生 I/O 错误。
如果到达流的末尾,read() 方法应该返回 -1。我的问题是,System.in.read() 什么时候返回 -1?
以下是示例代码:
import java.io.*;
class SystemInTest
public static void main(String[] args) throws IOException
InputStream in = System.in;
//InputStream in = new FileInputStream("h.txt");
int ch = 0;
while((ch = in.read()) != -1)
System.out.println(ch);
运行这段代码,输入“abc”,然后回车,结果是(在Linux下):
97
98
99
10
然后应用程序被阻塞并等待另一个输入。但我认为 while 循环“ch = in.read()”中的语句应该继续运行并在读取行终止字符并在控制台上打印 10 后返回 -1。如果是这样,则应终止该应用程序。但它被阻止了。
作为比较,如果我取消注释注释行,使用内容为“abc\n”的文件作为字节输入流,则应用程序将按预期终止,因为返回 -1。
System.in.read() 永远不会返回 -1 是真的吗?如果是这样,为什么 System.in 中 read() 方法的实现与 InputStream 的其他子类如 FileInputStream 不同?
【问题讨论】:
按 ctrl-D(可能两次)关闭输入流。如果您实际上没有关闭流,则说明您不在 EOF。 仅当输入实际结束时,例如echo abc | java SystemInTest
您的建议会阻止任何程序从命令行读取多行。流未关闭。它只是等待您输入下一个字符。例如,如果您使用java MyClass < somefile.txt
,将返回-1。
您的流永远不会返回-1
,因为它的大小未定义。在文件的情况下,文件的字节大小是已知的,当读取所有字节时,read()
然后返回 -1。相关:***.com/questions/24991803/…
【参考方案1】:
按Enter
仅表示您完成了一行,并不意味着您完成了整个“文件”。
如何完成文件取决于操作系统。在 Linux 上,它是 Ctrl+D
,您可以在许多程序中使用它来退出它们(而不是输入 exit
或 quit
)。在 Windows 上,它是Ctrl+Z
。
【讨论】:
【参考方案2】:输入流没有固定大小,因此您的程序正在进入无限循环并一次又一次地要求输入。 但是,h.txt 文件的大小是固定的,所以 while 会被终止。
【讨论】:
以上是关于关于 Java 中 System.in 的 read() 方法行为的混淆的主要内容,如果未能解决你的问题,请参考以下文章