我之前发布了同样的问题(Java reading standard output from an external program using inputstream),并在处理读取期间出现阻塞时找到了一些很好的建议(while(is.read()) != -1)),但我仍然无法解决问题。
在阅读了这个类似问题的答案后(Java InputStream blocking read,特别是Guss发布的答案),我开始相信如果程序是交互式的(即它从用户接收多个输入,并在随后的输入中呈现附加输出,并且只有在给出显式退出命令时才退出程序),那么使用is.read() != -1条件循环输入流不起作用。我承认我对多线程不太了解,但我认为我需要一种机制来及时暂停输入流线程(一个用于stdout,另一个用于stderr),当需要用户输入时,并在提供输入后恢复以防止阻塞。以下是我的当前代码,在标记的行上遇到了阻塞:
在阅读了这个类似问题的答案后(Java InputStream blocking read,特别是Guss发布的答案),我开始相信如果程序是交互式的(即它从用户接收多个输入,并在随后的输入中呈现附加输出,并且只有在给出显式退出命令时才退出程序),那么使用is.read() != -1条件循环输入流不起作用。我承认我对多线程不太了解,但我认为我需要一种机制来及时暂停输入流线程(一个用于stdout,另一个用于stderr),当需要用户输入时,并在提供输入后恢复以防止阻塞。以下是我的当前代码,在标记的行上遇到了阻塞:
EGMProcess egm = new EGMProcess(new String[]{directory + "/egm", "-o", "CasinoA", "-v", "VendorA", "-s", "localhost:8080/gls/MessageRobot.action ", "-E", "glss_env_cert.pem", "-S", "glss_sig_cert.pem", "-C", "glsc_sig_cert.pem", "-d", "config", "-L", "config/log.txt", "-H", "GLSA-SampleHost"}, new String[]{"PATH=${PATH}"}, directory);
egm.execute();
BufferedReader stdout = new BufferedReader(new InputStreamReader(egm.getInputStream()));
BufferedReader stderr = new BufferedReader(new InputStreamReader(egm.getErrorStream()));
EGMStreamGobbler stdoutprocessor = new EGMStreamGobbler(stdout, egm);
EGMStreamGobbler stderrprocessor = new EGMStreamGobbler(stderr, egm);
BufferedWriter stdin = new BufferedWriter(new OutputStreamWriter(egm.getOutputStream()));
stderrprocessor.run(); //<-- the block occurs here!
stdoutprocessor.run();
//EGM/Agent test cases
//check bootstrap menu
if(!checkSimpleResult("******** EGM Bootstrap Menu **********", egm))
{
String stdoutdump = egm.getStdOut();
egm.cleanup();
throw new Exception("can't find '******** EGM Bootstrap Menu **********'" +
"in the stdout" + "\nStandard Output Dump:\n" + stdoutdump);
}
//select bootstrap
stdin.write("1".toCharArray());
stdin.flush();
if(!checkSimpleResult("Enter port to receive msgs pushed from server ('0' for no push support)", egm)){
String stdoutdump = egm.getStdOut();
egm.cleanup();
throw new Exception("can't find 'Enter port to receive msgs pushed from server ('0' for no push support)'" +
"in the stdout" + "\nStandard Output Dump:\n" + stdoutdump);
}
public class EGMStreamGobbler implements Runnable{
}
很抱歉代码有点长,我的问题是:
1)是否有其他方法控制输入流(stdout, stderr)的处理过程,而不使用read()函数?或者我实现得不好?
2)多线程是开发输入流和输出流处理过程的正确策略吗?
注:如果有人能提供类似问题的解决方案,这将对我非常有帮助!