简体   繁体   English

在 Java 中,BufferedReader readLine 在交互式 shell 上阻塞

[英]In Java, BufferedReader readLine blocks on interactive shell

I have a jar file which keeps waiting for user input, process and print out result (in multiple lines) like this我有一个 jar 文件,它一直在等待用户输入、处理和打印结果(多行),就像这样

>Input sentence 1
Result 1
Result 2
>Input sentence 2
Result 1
Result 2
Result 3
>

The only way to exit this jar program is by pressing Ctrl + C.退出这个 jar 程序的唯一方法是按 Ctrl + C。

Now, I want to invoke this jar file from my java program.现在,我想从我的 java 程序中调用这个 jar 文件。 My code looks like this:我的代码如下所示:

processBuilder = new ProcessBuilder(PATH_TO_BIN);
Process process = processBuilder.start();
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

writer.write(inputSentence);
writer.newLine();
writer.flush();
String line;
while ((line = reader.readLine()) != null){ //<<<< it hangs here
    System.out.println(line);
}

My program can successfully print out the result returned by "jar" program, but it keep hanging at the next reader.readLine() and I can not provide the next input to "jar" program.我的程序可以成功打印出“jar”程序返回的结果,但它一直挂在下一个reader.readLine()并且我无法向“jar”程序提供下一个输入。

Is there any way to fix this issue?有没有办法解决这个问题?

Thanks in advance!提前致谢!

You could use one Thread to read and other to write, then it wouldn't block on read, like this:您可以使用一个线程读取,另一个线程写入,然后它不会在读取时阻塞,如下所示:

    ProcessBuilder processBuilder = new ProcessBuilder(PATH_TO_BIN);
    Process process = processBuilder.start();
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

      
    new Thread () {
      public void run() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        do {             
          line = reader.readLine();
          System.out.println(line);
        } while (line != null); // <<<< it waits here for next line of input 
      }
    }.start();
       

    // and here you can write something to the process InputSteram...
    writer.write(inputSentence);
    writer.newLine();
    writer.flush();

Method ready() from BufferedReader -Tells whether this stream is ready to be read.来自 BufferedReader 的方法 ready() - 告诉这个流是否准备好被读取。

You can use this method to check if stream is ready to be read and if yes you can do your work,您可以使用此方法检查流是否已准备好被读取,如果是,您可以完成您的工作,

while (reader.ready()){
//Do the processing
}

See if this works.看看这是否有效。

I'm going to base off of @Krzystof's answer, however I'm assuming you're going to be using Java 7 or 8 (+).我将基于@Krzystof 的回答,但是我假设您将使用 Java 7 或 8 (+)。

In which case, you should be using Try-With-Resources, as follows:在这种情况下,您应该使用 Try-With-Resources,如下所示:

public static void main (String[] args) throws java.lang.Exception {

    ProcessBuilder prBuilder = new ProcessBuilder("/path/to/bin");
    Process process = prBuilder.start();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())) | BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()))) {

        String line;

        while ((line = reader.readLine()) != null) {
            // Process input
        }

    } catch (IOException ex) {
        // Process IOException
    } finally {
        process.kill();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM