Я разместил здесь тот же вопрос несколько дней назад ( Java, читающий стандартный вывод из внешней программы с использованием inputtream ), и нашел несколько отличных советов по работе с блоком во время чтения (пока (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);</p>
<pre><code> 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);
}
</code>
...
</p>
<p>
public class EGMStreamGobbler implements Runnable{</p>
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: если кто-то может предложить аналогичную проблему с решением, это мне очень поможет!