【问题标题】:How to detect java process exit?如何检测java进程退出?
【发布时间】:2012-11-10 04:32:51
【问题描述】:

在一个 java 程序中,我正在生成一个用于 centOS 机器的 sh 脚本,它将使用 sox 和 lame 来解码 MP3 音频文件,然后分别对文件应用一些增益。我有一些问题让 Process.waitFor() 方法做任何事情,而不是无限期地挂起。这是代码:

            try
    {
    // TODO code application logic here
        String reviewPath = "/SomeDirectory/";
        String fileName = "FileName";
        String extension = ".mp3";
        StringBuilder sb = new StringBuilder();
        sb.append("#!/bin/bash\n");
        sb.append("cd " + reviewPath + "\n");
        sb.append("lame --decode " + fileName + extension + "\n"); 
        File script = new File(reviewPath + fileName + ".sh");
        script.createNewFile();
        script.setExecutable(true);
        FileWriter writer = new FileWriter(script);
        writer.write(sb.toString());
        writer.close();
        Process p = Runtime.getRuntime().exec(script.getAbsolutePath());
        String line;
        BufferedReader bri = new BufferedReader
            (new InputStreamReader(p.getInputStream()));
        BufferedReader bre = new BufferedReader
            (new InputStreamReader(p.getErrorStream()));
        while ((line = bri.readLine()) != null) {
            System.out.println(line);
        }
        bri.close();
        while ((line = bre.readLine()) != null) {
            System.out.println(line);
        }
        bre.close();
        p.waitFor();
        System.out.println("Done.");

    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
    }

奇怪的是,当我运行它手动生成的 .sh 文件时,它会很好地运行并退出,但是当我从 java 中的进程对象执行它时,它永远不会退出。进程的 exitValue 始终为“进程尚未退出”。我尝试将 set -e 添加到脚本中,然后退出到脚本的末尾。没有使用 kill 命令(我真的不认为我可以在这里做)我不知道这里发生了什么。有什么建议吗?

【问题讨论】:

  • 为什么要在 java 中生成一个 shell 脚本然后运行它而不是在 java 中执行整个解码过程,这取决于解码 API 的可用性?
  • 也许你需要读出输出流?
  • 许多进程在输出缓冲区被清空之前不会退出,这意味着您需要读取进程输入流的内容直到其为空(返回 -1)
  • 由于种种原因,简单来说,这些机器已经是维护的噩梦,但配置已经需要 SOX 和 LAME,所以我们选择使用它们。
  • 我认为您最好使用 ProcessBuilder API-docs.oracle.com/javase/1.5.0/docs/api/java/lang/Process.html。查看 javadoc 顶部部分中的示例,该示例与您正在执行的操作非常接近。

标签: java bash process io centos


【解决方案1】:

在启动过程后添加类似while(p.getInputStream().read() != -1); 的内容。缓冲区将被填满,进程将停止等待某些内容(在本例中为您的程序)从中读取以释放空间。

【讨论】:

    【解决方案2】:

    我想通了!这里的问题确实是需要刷新输出流以使应用程序退出,但仅从流中读取是不够的。我使用了 Suresh Koya 的建议并使用了 processBuilder api,并在启动之前重定向了进程上的错误流,并从流中读取。这解决了我遇到的问题:D

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多