【问题标题】:Trying to run an exe file created from a cpp file in java尝试运行从java中的cpp文件创建的exe文件
【发布时间】:2018-04-29 14:02:32
【问题描述】:

我正在尝试运行从 java 中的 cpp 程序创建的可执行文件。如果我双击 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();}

【问题讨论】:

  • “卡住”是什么意思?请read about how to ask good questions。我也推荐this StackOverflow question checklist
  • 程序没有结束,它没有打印整个输出。同样,如果我在 Java 之外双击可执行文件,它工作正常。 @Someprogrammerdude
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建 minimal reproducible example。使用edit 链接改进您的问题 - 不要通过 cmets 添加更多信息。谢谢!
  • @GhostCat:这里有足够的信息。它只是看起来不像。对于任何需要提出问题的人来说,MVCE 都是不可能的。
  • 这是一个有效的问题,不是题外话,下面已经回答了。

标签: java pipe deadlock processbuilder


【解决方案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); 合并标准输出和标准错误; getErrorStream 之后返回一个空输入流。
  • @user2357112:因为当我在手册中查找它时,我得到了相反的答案。
  • 这不是the manual 在我读到它时所说的:“如果该值设置为 true,那么:[...] Process.getErrorStream() 返回的流将始终为 null输入流”
猜你喜欢
  • 1970-01-01
  • 2020-01-23
  • 2012-05-27
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2010-12-27
相关资源
最近更新 更多