如何使用bash将输入传递给Java程序

Che*_*tan 21 java bash input pipe

我的Java程序正在监听标准输入:

InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
while(true){
    try {
        String inputStr = null;
        if((inputStr=bufReader.readLine()) != null) {
            ...
        }
        else {
            System.out.println("inputStr is null");
        }
    }
    catch (Exception e) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想从bash管道输入到这个程序.我尝试了以下方法:

echo "hi" | java -classpath ../src test.TestProgram
Run Code Online (Sandbox Code Playgroud)

但它只是印刷inputStr is null无限次.我究竟做错了什么?

编辑1:更新了问题以包含更多代码/上下文.


编辑2:

看起来我遇到了与此OP相同的问题:Java中的命令行管道输入

如何修复程序以便我可以输入管道进行测试,但正常运行程序将允许用户在标准输入上输入输入?

Che*_*tan 6

固定它.在输入管道完成后,readLine()保持返回null,因此无限循环保持循环.

修复是在readLine()返回null 时从无限循环中断开.


sli*_*lim 5

您拥有while(true),因此您将获得无限循环。

break在循环中添加某个位置是修复它的一种方法。但这不是一个好的样式,因为读者必须在循环中四处寻找,以了解是否以及何时退出。

最好让您的while陈述清楚地表明退出条件是什么:

String inputStr = "";
while(inputStr != null) {
    inputStr=bufReader.readLine(); 
    if(inputStr != null) {
        ...
    } else {
        System.out.println("inputStr is null");
    }
}
Run Code Online (Sandbox Code Playgroud)


Arm*_*and 5

我喜欢 slim 的答案,只是我倾向于以不同的方式处理它。这是我用来逐行读取文本流的基本模板。

try {
    // Wrap the System.in inside BufferedReader
    // But do not close it in a finally block, as we 
    // did no open System.in; enforcing the rule that
    // he who opens it, closes it; leave the closing to the OS.
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String line;
    while ((line = in.readLine()) != null) {
        // TODO: Handle input line
    }

    // Null was received, so loop was aborted.

} catch (IOException e) {
    // TODO: Add error handler
}
Run Code Online (Sandbox Code Playgroud)

如果我正在读取文件,我会稍微更改它,以像这样关闭文件

try {
    File file = new File("some_file.txt");

    // Wrap the System.in inside BufferedReader
    // But do not close it in a finally block, as we
    // did no open System.in; enforcing the rule that
    // he who opens it, closes it; leaves the closing to the OS.
    BufferedReader in = new BufferedReader(new FileReader(file));
    try {
        String line;
        while ((line = in.readLine()) != null) {
            // TODO: Handle input line
        }

        // Null was received, so loop was aborted.

    } finally {
        try {
            in.close();
        } catch (IOException e) {
        }
    }

} catch (IOException e) {
    // TODO: Add error handler
}
Run Code Online (Sandbox Code Playgroud)