【发布时间】:2010-11-09 11:40:10
【问题描述】:
几天前我在这里发布了同样的问题(Java reading standard output from an external program using inputstream),我发现了一些很好的建议来处理阅读时的阻塞(while(is.read())!= -1)) ,但我仍然无法解决问题。
在阅读了这个类似问题的答案后,
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”}、新字符串[]{“PATH=${PATH}”}、目录); 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);
}
...
公共类 EGMStreamGobbler 实现 Runnable{
私有 BufferedReader 流内; 私有 EGMProcess egm; 公共 EGMStreamGobbler(BufferedReader isr,EGMProcess aEGM) { 流内 = isr; egm = 临时股东大会; } 公共无效运行() { 尝试{ 诠释 c; 而((c = instream.read()) != 1) { egm.processStdOutStream((char)c); } } 捕获(IOException e) { e.printStackTrace(); } }}
对于代码的长度,我深表歉意,但我的问题是,
1) 有什么方法可以在不使用 read() 的情况下控制接收输入流(stdout、stderr)的过程?还是我执行得不好?
2) 多线程是开发接收输入流和编写输出过程的正确策略吗?
PS:如果有人能提供类似问题的解决方案,对我有很大帮助!
【问题讨论】: