Я пытаюсь запустить исполняемый файл, созданный из программы cpp в java. Если я дважды щелкну файл exe, он будет работать нормально, но если я запустил файл с помощью ProcessBuilder, он по какой-то причине застрянет, распечатает большую часть ожидаемого вывода и не продолжит работу, а также всю программу Java отвечая. вот мой код:
String filePath = FirstScreenController.getFile().getPath();
ProcessBuilder launcher = new ProcessBuilder("ClusteringProgram\\Release\\main.exe",filePath);
launcher.redirectErrorStream(true);
try {
/*File file = FirstScreenController.getFile();
Path newPath = Paths.get(System.getProperty("user.dir")+"\\ClusteringProgram").resolve("K12.fasta");//Moving the file to the
Files.copy(Paths.get(file.getPath()), newPath, StandardCopyOption.REPLACE_EXISTING);*/
System.out.println("Execution started");
p = launcher.start();
InputStream stderr = p.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
p.waitFor();//Waiting for the process to finish running
System.out.println("Execution completed");
} catch (IOException | InterruptedException e) {e.printStackTrace();}
Программа не заканчивается, она не распечатывает весь вывод. Опять же, если я дважды щелкну исполняемый файл вне Java, он будет работать нормально. @Someprogrammerdude
Вопросы, требующие помощи по отладке («почему этот код не работает?»), Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения в самом вопросе. Вопросы без четкой постановки проблемы не будут полезны другим читателям. См .: Как создать минимальный воспроизводимый пример. Используйте ссылку редактировать, чтобы улучшить свой вопрос - не добавляйте дополнительную информацию через комментарии. Спасибо!
@GhostCat: Здесь достаточно информации. Это просто не похоже. MVCE будет невозможным для любого, кому нужно задать вопрос.
Это правильный вопрос, он не не по теме, и на него дан ответ ниже.
@ Джошуа: Почему это невозможно? По крайней мере, показать нам сторону C++ и устранить зависимость от filePath было бы хорошим началом, и для этого не нужно заранее знать, что не так.
@ user2357112: Я не буду говорить явно, потому что это неочевидно. Проблема так или иначе зависит от конкретных размеров буфера ввода-вывода и конкретных выходных данных второй программы. Но в этом фрагменте нет размеров буфера ввода-вывода, и почти наверняка нет и в коде C++.




Закройте свой поток. Вот что заставляет вас зависать. Я довольно часто пишу такой код.
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close(); // You need this or p can hang
p.waitFor();
Кроме того, вы вызвали Весь остальной ответ неверен. Я не знаю, что вызывает тупик. Я оставляю здесь большой фрагмент кода на случай, если это какая-то странная ошибка библиотеки, и оказывается, что для ее решения требуется техника двухпоточного чтения.launcher.redirectStandardError(true);, поэтому вам действительно нужно все это, чтобы собрать вместе как stdout, так и stderr:
final object lock = new object();
InputStream stdout = p.getInputStream();
InputStreamReader isr = new InputStreamReader(stdout);
BufferedReader br = new BufferedReader(isr);
final InputStream stderr = p.getErrorStream();
one = new Thread() {
public void run() {
InputStreamReader isr2 = new InputStreamReader(stderr);
BufferedReader br2 = new BufferedReader(isr2);
while ((line2 = br2.readLine()) != null) {
synchronized(lock) {
System.out.println(line2);
}
}
br2.close(); // you need this or p can hang
}
};
one.start();
while ((line = br.readLine()) != null) {
synchronized(lock) {
System.out.println(line);
}
}
br.close(); // You need this or p can hang
for (;;) {
try {
one.join();
break;
} catch (InterruptedException v) {
/* if there's something that might want the main thread's attention handle it here */
}
}
p.waitFor();
Почему вы читаете с getErrorStream? launcher.redirectStandardError(true); объединяет stdout и stderr; После этого getErrorStream возвращает нулевой входной поток.
@ user2357112: Потому что, когда я поискал его в руководстве, я получил противоположный ответ о том, что он делает.
Это не то, что говорит руководство, когда я его читал: «Если значение установлено в true, то: [...] поток, возвращаемый Process.getErrorStream (), всегда будет нулевым входным потоком»
Что вы имеете в виду, говоря «застрять»? Пожалуйста, читай о том, как задавать хорошие вопросы. Еще рекомендую этот контрольный список вопросов StackOverflow.