关于 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,您可以在许多程序中使用它来退出它们(而不是输入 exitquit)。在 Windows 上,它是Ctrl+Z

【讨论】:

【参考方案2】:

输入流没有固定大小,因此您的程序正在进入无限循环并一次又一次地要求输入。 但是,h.txt 文件的大小是固定的,所以 while 会被终止。

【讨论】:

以上是关于关于 Java 中 System.in 的 read() 方法行为的混淆的主要内容,如果未能解决你的问题,请参考以下文章

关于java scanner类简化输入的一点疑问

关于JAVA字符串提取下标问题

关于 Java 的 Scanner类!!!!

java中 index怎么用啊,这个关于index的代码看不懂,求讲解~~

从 Java 中读取 System.in 的最快方法是啥?

Java系统流