当我使用System.in
对象的Scanner
方法阅读nextInt()
时,它会阻止,直到我写下内容并按 Enter 。但是当我在hasNext()
方法之后使用它时只有hasNext()
阻塞,直到我写东西并按 Enter (或使用 ctrl + z 组合在Windows上。)
while (input.hasNext())
{
int num = input.nextInt();
... do things here
}
有人可以解释这究竟是如何运作的?它是否使用\n
字符或只是等我按 Enter 键?为什么我在读取文件时没有这种情况(在读取文件时没有阻塞)。 Aren他们俩都流了?
答案 0 :(得分:1)
1)在你的代码中," hasNext"是阻止等待输入的那个。当" hasNext"返回,这意味着有可用的输入," next"不阻止。
来自JavaDoc for" hasNext": 此方法可能会在等待输入扫描时阻塞。
2)从文件中读取时,所有内容都在那里(在文件中),所以" hasNext"将立即返回true,直到到达文件末尾。所以没有阻止。
从System.in读取时,输入是在您键入时生成的,因此它总是等待,因为它希望您使用键盘写入更多数据。
答案 1 :(得分:0)
System.in是与在给定操作系统上运行程序的JVM进程的stdin
(操作系统进程标准的文件描述符)相关联的InputStream(即流)。
史蒂文斯和拉戈的开创性工作Advanced programming in Unix Environment非常有说服力地描述了幕后发生的事情。基本上,Java实现委托给您的操作系统上的标准I / O库(大约40年前由Dennis Ritchie编写/移植!)。
标准I / O库的两个特征至关重要:
标准I / O库仔细选择缓冲区的默认值,并且最大限度地减少read
和write
系统调用的数量,从而减少执行I所需的CPU时间/ O操作。根据缓冲的发生方式,有三种流:全缓冲,行缓冲和无缓冲。
现在,在上面的书中,以下内容见5.4节:
大多数实现默认使用以下类型的缓冲: 标准错误始终是无缓冲的。所有其他流都是行 如果它们引用终端设备则缓冲;否则,他们是完全的 缓冲的。本书中讨论的四个平台遵循这些 标准I / O缓冲的约定:标准错误是无缓冲的, 对终端设备开放的流是行缓冲,所有其他 流被完全缓冲。
这意味着默认情况下,标准输入将被阻止(好像没有任何反应),直到您按下换行符。如果您重定向文件中的输入(例如java MyProgram < foo.txt
),那么您正在读取默认情况下完全缓冲的流。
这里有一些低级细节,但是当程序从终端设备读取时,它会阻止换行字符或EOF字符被按下以刷新缓冲区。从文件读取时,由于流是完全缓冲的,因此当程序开始读取缓冲区时,您不会注意到缓冲区已填满并刷新。读取EOF时,hasNext()
都会返回false。
答案 2 :(得分:-1)
import java.util.Scanner;
public class EndOfFile
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
for(int i = 1; sc.hasNext()== true; i++)
{
System.out.println(i + " " + sc.nextLine());
}
}
}