2013-07-31 58 views
0

出于某种原因,我在将输出发送到我在Java中创建的进程时遇到问题。外部进程在命令提示符下运行,特别的是我可以点击它,输入命令,然后输入,我将从程序中获得输出。此外,我的程序可以读取来自程序的所有输出,它只是无法发送任何内容。发送输出到外部进程

不管怎么说,这里是相关的代码我使用的只是不工作...

try { 
    ProcessBuilder builder=new ProcessBuilder(args); 
    builder.redirectErrorStream(true); 
    final Process p=builder.start(); 
    // Process has been created and is running 
    try { 
     String b=""; 
     BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     final BufferedWriter output = new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); 
     new Thread(){public void run(){ 
      // This thread will periodically send "get_time" to the process to get an update on its progress 
      while(true) 
      { 
       try { 
        Thread.sleep(1000); 
        p.exitValue(); 
        // p.exitValue() only works when process has ended, so normal code goes in the catch block 
        output.close(); 
        break; 
        // Leave the infinite loop if the program has closed 
       } catch (IOException ex) { 
        Logger.getLogger(OvMusicUI.class.getName()).log(Level.SEVERE, null, ex); 
        break; 
        // Leave the infinite loop if we tried closing our output stream, but it was already closed 
       } catch (InterruptedException ex) { 
        Logger.getLogger(OvMusicUI.class.getName()).log(Level.SEVERE, null, ex); 
       } catch (IllegalThreadStateException e) { 
        try { 
         System.out.println("Outputted: get_time"); 
         output.write("get_time" + System.lineSeparator()); 
         output.flush(); 
         // Give the process some input 
        } catch (IOException ex) { 
         Logger.getLogger(OvMusicUI.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 
     }}.start(); 
     while((b = input.readLine()) != null){ 
      System.out.println(new Time(System.currentTimeMillis()).toString() + " " + b); 
      // Log all output the process gives 
     } 
     input.close(); 
    } catch (IOException ex) { 
     Logger.getLogger(OvMusicUI.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    // More code here 
} catch (IOException ex) { 
    Logger.getLogger(OvMusicUI.class.getName()).log(Level.SEVERE, null, ex); 
} 

如果需要,我可以举个例子命令和外部程序的名称正在运行,这样你可以自己试试...

谢谢!

编辑:这是一个传递给ProcessBuilder的示例:Arrays.asList("VLC\vlc.exe", "-Irc", "-vvv", "http://www.youtube.com/watch?v=xfeys7Jfnx8", "--sout", "file/ogg:Untitled 1.ogg", "--play-and-exit", "--rc-quiet")。唯一的区别是我使用绝对路径而不是相对路径。该方案是VLC媒体播放器2.0.7。

+0

你是否将另一个程序的'stdout'重定向到你的Java代码? –

+1

作为一个方面说明,如果使用'private static Logger logger = Logger.getLogger(name)'类字段,则代码将更加简洁和快得多。 – chrylis

+1

总是继续并发布有用的信息,例如您打电话的外部程序。 – chrylis

回答

2

您的代码有几个问题。首先,您通常应该使用而不是为您的常规控制流程使用异常:它很昂贵,难以阅读,并且使处理实际错误变得更加困难。产生另一个调用p.waitFor()Thread通常会更好,并通知您的主线程完成,例如wait/notify

此外,您的构建与无限循环,并使用break而不是return将使您的代码更难调试;而是使用Timer

它看起来像你的外部程序的输出可能工作正常,但问题是只是读取它的输出。该程序可能会缓冲它自己的输出,或者可能检测到它没有以交互方式运行并且行为不同。