Попытка запустить exe-файл, созданный из файла cpp в java

Я пытаюсь запустить исполняемый файл, созданный из программы 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();}

Что вы имеете в виду, говоря «застрять»? Пожалуйста, читай о том, как задавать хорошие вопросы. Еще рекомендую этот контрольный список вопросов StackOverflow.

Some programmer dude 29.04.2018 16:06

Программа не заканчивается, она не распечатывает весь вывод. Опять же, если я дважды щелкну исполняемый файл вне Java, он будет работать нормально. @Someprogrammerdude

BitThinker483 29.04.2018 16:10

Вопросы, требующие помощи по отладке («почему этот код не работает?»), Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения в самом вопросе. Вопросы без четкой постановки проблемы не будут полезны другим читателям. См .: Как создать минимальный воспроизводимый пример. Используйте ссылку редактировать, чтобы улучшить свой вопрос - не добавляйте дополнительную информацию через комментарии. Спасибо!

GhostCat 29.04.2018 16:11

@GhostCat: Здесь достаточно информации. Это просто не похоже. MVCE будет невозможным для любого, кому нужно задать вопрос.

Joshua 29.04.2018 20:47

Это правильный вопрос, он не не по теме, и на него дан ответ ниже.

Ingo Kegel 29.04.2018 22:40

@ Джошуа: Почему это невозможно? По крайней мере, показать нам сторону C++ и устранить зависимость от filePath было бы хорошим началом, и для этого не нужно заранее знать, что не так.

user2357112 supports Monica 30.04.2018 01:41

@ user2357112: Я не буду говорить явно, потому что это неочевидно. Проблема так или иначе зависит от конкретных размеров буфера ввода-вывода и конкретных выходных данных второй программы. Но в этом фрагменте нет размеров буфера ввода-вывода, и почти наверняка нет и в коде C++.

Joshua 30.04.2018 02:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
99
1

Ответы 1

Закройте свой поток. Вот что заставляет вас зависать. Я довольно часто пишу такой код.

    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 supports Monica 30.04.2018 01:29

@ user2357112: Потому что, когда я поискал его в руководстве, я получил противоположный ответ о том, что он делает.

Joshua 30.04.2018 01:35

Это не то, что говорит руководство, когда я его читал: «Если значение установлено в true, то: [...] поток, возвращаемый Process.getErrorStream (), всегда будет нулевым входным потоком»

user2357112 supports Monica 30.04.2018 01:38

Другие вопросы по теме