Я написал один и тот же вопрос здесь несколько дней назад (Java reading standard output from an external program using inputstream), и я нашел несколько отличных советов при работе с блоком во время чтения (while (is.read())! = -1)), но я все еще не могу решить проблему.Блоки ввода-вывода Java IO при чтении стандартного вывода и стандартная ошибка внешней программы С
После прочтения ответов на этот подобный вопрос,
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"}, 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); }
...
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: если кто-то может предоставить аналогичную проблему с решением, это мне очень поможет!