首页 > 解决方案 > 热腾腾的 java --- 使用 bash 中的 java 处理标准输入时的一些奇怪行为

问题描述

main假设我有以下(愚蠢的)java程序,它在和之间来回循环aux,每当y输入a时:

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 中,我得到的答案与运行时不同

$ java Minimal

并键入(交互式)y后跟<ENTER>--- 似乎等同于上面自动输入的内容printf。有任何想法吗?

标签: javabashjava.util.scannerstdin

解决方案


不同之处在于缓冲。 Scanner缓冲其输入,因此它可能一次消耗多行来自System.in. 使用printf时,数据立即可用,因此全部Scannermain(). 因此,没有更多数据可供Scanner在每次调用中创建的aux()读取。

当您以交互方式运行程序时,终端会在您输入数据时逐行发送数据,因此在每次读取时没有任何额外的数据可用于缓冲。

为避免此问题,请不要Scanner为同一个InputStream.


推荐阅读