1

我正在尝试从我的 Java 应用程序执行一个进程,当我从控制台执行这个进程时它工作正常,但是当我执行 getRuntime().exec() 时它开始但永远不会结束,没有异常,没有退出值。我尝试执行的过程是 pdftops.exe,这是一个将 PDF 文件转换为 PostScript 的应用程序。当我尝试转换小文件(从 Java 执行)时,它工作正常,问题是转换可能需要更长时间(从 20 到 60 秒)的较大 PDF。我认为问题可能是执行时间太长。下面是调用程序的一段代码(命令行简化,input.pdf和output.ps放在我家目录下的一个文件夹里,pdftops.exe放在Desktop里):

String comando = "pdftops.exe input.pdf output.ps";
System.out.println("Executing "+comando);
try {
    Process pr = Runtime.getRuntime().exec(comando);            
    pr.waitFor();      
    System.out.println("Finished");
}
catch (IOException ex){
    ex.printStackTrace();
}
catch(InterruptedException ex){
    ex.printStackTrace();
}

编辑:阅读过程的 ErrorStream 解决了这个问题:

try {
    System.out.println(comando);
    Process process = Runtime.getRuntime().exec(comando);            

    String line;

    InputStream stderr = process.getErrorStream ();

    BufferedReader reader = new BufferedReader (new InputStreamReader(stderr));

    line = reader.readLine();
    while (line != null && ! line.trim().equals("--EOF--")) {
        System.out.println ("Stdout: " + line);
        line = reader.readLine();
    }
}
catch (IOException ex){
    ex.printStackTrace();
}
4

3 回答 3

4

不是立即回答您的问题,但可能有助于捕获过程的错误/输出流,以便您知道那里发生了什么(假设它产生了一些东西)。

使用 java 7,您可以使用非常方便的ProcessBuilder并将错误流合并到输出中...

例如,它可以等待一些输入吗?

于 2012-12-18T10:09:50.917 回答
2

我会使用ProcessBuilder(类似于 Jan 之前所说的),如果您使用 Java 5,至少类似下面的内容可能会告诉您错误是什么……

public void execute () throws IOException, InterruptedException
{
    ProcessBuilder pb = new ProcessBuilder("pdftops.exe", "input.pdf", "output.ps");

    Process process = pb.start();

    System.out.println("Error stream:");
    InputStream errorStream = process.getErrorStream();
    printStream(errorStream);

    process.waitFor();

    System.out.println("Output stream:");
    InputStream inputStream = process.getInputStream();
    printStream(inputStream);
}

private void printStream (InputStream stream) throws IOException
{
    BufferedReader in = new BufferedReader(new InputStreamReader(stream));
    String inputLine;
    while ((inputLine = in.readLine()) != null)
        System.out.println(inputLine);
    in.close();
}
于 2012-12-18T10:23:31.453 回答
0

如果您浏览 java 文档,您会发现:

waitFor : Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
Returns: the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination.
Throws: InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

我的猜测是,对于大文件,它会遇到一个时间难题,这会混淆执行。可能您可以在这里检查执行过程的完成状态,如下所示:

  if(Process.exitValue()==0)
  break;

这将确保一旦您的执行结束,无限或过度激进的循环将不会成为执行的最终结果。

于 2012-12-18T10:12:46.730 回答