滚烫 java --- 使用来自 bash 的 java 处理标准输入时出现一些奇怪的行为
piping hot java --- some strange behavior when processing stdin with java from bash
假设我有以下(愚蠢的)java 程序,它在 main
和 aux
之间来回循环,每当输入 y
时:
import java.util.Scanner;
public class Minimal {
public static void main(String[] args) {
System.out.println("in main...");
Scanner scanner = new Scanner(System.in);
String s;
while(scanner.hasNextLine()) {
s = scanner.nextLine();
System.out.println(s);
if(s.equals("y")) {
aux();
System.out.println("in main...");
}
}
}
public static void aux() {
System.out.println("in aux...");
Scanner scanner = new Scanner(System.in);
String s;
while(scanner.hasNextLine()) {
s = scanner.nextLine();
System.out.println(s);
if(s.equals("y")) {
return;
}
}
}
}
但是,当我 运行
$ javac Minimal.java
$ printf "y\ny\ny\ny\ny\ny\ny\n" | java Minimal
在 bash 中得到的答案与在 运行ning
中得到的答案不同
$ java Minimal
并(交互地)键入 y
后跟 <ENTER>
--- 似乎等同于上面使用 printf
自动输入的内容。有什么想法吗?
区别在于缓冲。 Scanner
缓冲其输入,因此它可能一次消耗来自 System.in
的不止一行。当您使用 printf
时,数据立即可用,因此它全部由 main()
中的 Scanner
实例使用。因此,在每次调用 aux()
时创建的 Scanner
没有更多数据可供读取。
当您以交互方式 运行 程序时,终端会在您输入数据时逐行发送数据,因此每次读取时没有任何额外数据可用于缓冲。
为避免此问题,请不要为同一个 InputStream
.
创建多个 Scanner
实例
假设我有以下(愚蠢的)java 程序,它在 main
和 aux
之间来回循环,每当输入 y
时:
import java.util.Scanner;
public class Minimal {
public static void main(String[] args) {
System.out.println("in main...");
Scanner scanner = new Scanner(System.in);
String s;
while(scanner.hasNextLine()) {
s = scanner.nextLine();
System.out.println(s);
if(s.equals("y")) {
aux();
System.out.println("in main...");
}
}
}
public static void aux() {
System.out.println("in aux...");
Scanner scanner = new Scanner(System.in);
String s;
while(scanner.hasNextLine()) {
s = scanner.nextLine();
System.out.println(s);
if(s.equals("y")) {
return;
}
}
}
}
但是,当我 运行
$ javac Minimal.java
$ printf "y\ny\ny\ny\ny\ny\ny\n" | java Minimal
在 bash 中得到的答案与在 运行ning
中得到的答案不同$ java Minimal
并(交互地)键入 y
后跟 <ENTER>
--- 似乎等同于上面使用 printf
自动输入的内容。有什么想法吗?
区别在于缓冲。 Scanner
缓冲其输入,因此它可能一次消耗来自 System.in
的不止一行。当您使用 printf
时,数据立即可用,因此它全部由 main()
中的 Scanner
实例使用。因此,在每次调用 aux()
时创建的 Scanner
没有更多数据可供读取。
当您以交互方式 运行 程序时,终端会在您输入数据时逐行发送数据,因此每次读取时没有任何额外数据可用于缓冲。
为避免此问题,请不要为同一个 InputStream
.
Scanner
实例