几天前我在这里发布了同样的问题(Java 使用 inputstream 从外部程序读取标准输出),我发现了一些很好的建议来处理读取时的块(while(is.read()) != -1)),但我仍然无法解决问题。
在阅读了这个类似问题的答案后,
Java InputStream 阻塞读取 (尤其是 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);
}
...
public class EGMStreamGobbler implements Runnable{
private BufferedReader instream;
private EGMProcess egm;
public EGMStreamGobbler(BufferedReader isr, EGMProcess aEGM)
{
instream = isr;
egm = aEGM;
}
public void run()
{
try{
int c;
while((c = instream.read()) != 1)
{
egm.processStdOutStream((char)c);
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
我为代码的长度道歉,但我的问题是,
1) 有没有办法在不使用 read() 的情况下控制接收输入流(stdout、stderr)的过程?还是我只是执行得很糟糕?
2) 多线程是开发接收输入流和编写输出过程的正确策略吗?
PS:如果有人能提供类似问题的解决方案,对我有很大帮助!