进程不返回它的输出

时间:2018-12-08 09:52:09

标签: java process io applescript

我写了一个简单的AppleScript,我试图从Java调用该过程,该过程将使用osascript来运行实际的脚本。该脚本似乎已执行,但未输出任何内容。我尝试从Terminal运行相同的脚本,并且按预期方式工作-我得到了类似{{300, 450}, {500, 500}}的输出。

    public void macTest() throws ScriptException, IOException, InterruptedException {
        final String script= "tell application \"System Events\" to tell application process \"Eclipse\"\n" + 
                "   get {size, position} of window 1\n" + 
                "end tell";

        System.out.println(runProcess(String.format("osascript -e '%s'", script)));
    }

    public static String runProcess(String cmdline) throws IOException, 
    InterruptedException { 
        Process p = Runtime.getRuntime().exec(cmdline); 
        p.waitFor(); 
        try { 
            return readContents(p.getInputStream()); 
        } finally { 
            p.destroy(); 
        } 
    } 

    public static String readContents(InputStream inputStream) 
            throws IOException { 
        StringBuilder contents = new StringBuilder(); 
        BufferedReader reader = new BufferedReader(new InputStreamReader( 
                inputStream)); 
        try { 
            String line; 
            while ((line = reader.readLine()) != null) {
                contents.append(line).append("\n"); 
            } 
        } finally { 
            reader.close(); 
        } 
        return contents.toString().trim(); 
    } 

这里输入流似乎是空的。如何获取Java进程的输出?

1 个答案:

答案 0 :(得分:0)

从Java调用系统进程可能会有些棘手:意识到隐式多线程正在以下环境下运行:

  • 一方面,您的Java程序在JVM上运行(一个进程)。
  • 另一方面,存在您启动的子进程,该子进程独立于JVM运行。这个过程肯定是在将数据写入其输出流和/或错误流(甚至可能从其输入流读取数据,但事实并非如此)。

简而言之:您必须启动一个线程来读取子流程的输出流(通过readContents方法),并启动另一个线程来读取子流程的错误流。并且,一旦它们开始,您可以调用waitFor方法来阻塞主线程,直到子进程结束。