几天前我在这里发布了同样的问题(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:如果有人能提供类似问题的解决方案,对我有很大帮助!