我几天前在这里发布了同样的问题(Java使用输入流读取外部程序的标准输出),我在阅读时遇到了一些块的优点(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"}, 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);
}
Run Code Online (Sandbox Code Playgroud)
...
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)有没有办法控制输入流(stdout,stderr)的过程而不使用read()?或者我只是执行这个很糟糕?
2)多线程是否是开发输入流和编写输出过程的正确策略?
PS:如果有人能提出解决方案的类似问题,它将对我有很大的帮助!
代替
stderrprocessor.run(); //<-- the block occurs here!
stdoutprocessor.run();
Run Code Online (Sandbox Code Playgroud)
你需要启动线程:
Thread errThread = new Thread(stderrprocessor);
errThread.setDaemon( true );
errThread.start();
Thread outThread = new Thread(stdoutprocessor);
outThread.setDaemon( true );
outThread.start();
Run Code Online (Sandbox Code Playgroud)
run()只是一个指定的方法Runnable. Thread.start()呼吁run()在Runnable一个新的Thread.
| 归档时间: |
|
| 查看次数: |
2687 次 |
| 最近记录: |