2014-01-21 116 views
3

我試圖創建一個程序,允許我通過終端(這是覆盆子pi的OmxPlayer,如果你想知道)用參數執行一個命令,但是我會希望能夠在我啓動命令後與它進行交互。使用processBuilder執行shell命令並與它進行交互

例如我願意做的事情:omxplayer -WIN X1 Y1 X2 Y2 然後就可以按「P」暫停視頻/音頻媒體

我已經擁有的東西,可以啓動omxplayer與參數(實際上它是「ls」,但它應該以完全相同的方式工作),但我不明白如何通過processBuilder啓動命令後如何與終端進行交互。

這裏就是我此刻的了:

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.ArrayList; 
import java.util.List; 

public class Main1 { 

    public static void main(String a[]){ 

     InputStream is = null; 
     ByteArrayOutputStream baos = null; 
     List<String> commands = new ArrayList<String>(); 
     commands.add("ls"); 
     commands.add("-l"); 
     commands.add("/"); 
     ProcessBuilder pb = new ProcessBuilder(commands); 
     try { 
      Process prs = pb.start(); 
      is = prs.getInputStream(); 
      byte[] b = new byte[1024]; 
      int size = 0; 
      baos = new ByteArrayOutputStream(); 
      while((size = is.read(b)) != -1){ 
       baos.write(b, 0, size); 
      } 
      System.out.println(new String(baos.toByteArray())); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      try { 
       if(is != null) is.close(); 
       if(baos != null) baos.close(); 
      } catch (Exception ex){} 
     } 
    } 
} 
+0

看看這裏的答案,我認爲這會有所幫助。 http://stackoverflow.com/questions/17216049/executing-two-commands-with-process-builder – SpaceCowboy

+0

這與我想要做的接近,但不完全一樣。我試圖與我執行的命令進行交互,而不是在第一個命令之後立即執行第二個命令:/ – Equinox

+0

如何寫入進程的STDIN:http://docs.oracle.com/javase/7/docs/api /java/lang/Process.html#getOutputStream()? – Fildor

回答

2

「(實際上是‘LS’,但它應該工作完全相同的方式)」

不,事實並非如此。因爲'ls'進程在調用之後立即返回。另一方面,您的omixplayer是交互式的,將在運行時接受命令。

你要做的:

  • 創造出實現Runnable類,讓這個類從prs.getInputStream閱讀()。你將需要這個,因爲.read()會阻塞並等待新數據讀取。

  • 獲取Process對象的OutputStream(prs.getOutputStream())。您寫入OutputStream的所有內容都將從您的omixplayer中讀取。不要忘了刷新OutputStream,並且每個命令都需要在結尾執行一個「\ n」。

就像是:

public class TestMain { 
    public static void main(String a[]) throws InterruptedException { 

     List<String> commands = new ArrayList<String>(); 
     commands.add("telnet"); 
     commands.add("www.google.com"); 
     commands.add("80"); 
     ProcessBuilder pb = new ProcessBuilder(commands); 
     pb.redirectErrorStream(true); 
     try { 

      Process prs = pb.start(); 
      Thread inThread = new Thread(new In(prs.getInputStream())); 
      inThread.start(); 
      Thread.sleep(2000); 
      OutputStream writeTo = prs.getOutputStream(); 
      writeTo.write("oops\n".getBytes()); 
      writeTo.flush(); 
      writeTo.close(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class In implements Runnable { 
    private InputStream is; 

    public In(InputStream is) { 
     this.is = is; 
    } 

    @Override 
    public void run() { 
     byte[] b = new byte[1024]; 
     int size = 0; 
     try { 
      while ((size = is.read(b)) != -1) { 
       System.err.println(new String(b)); 
      } 
      is.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 

P.S:請記住這個例子是快速的髒。

+0

謝謝你的幫助!這真的幫助我們使用流程建設者:) – Equinox

+0

很高興聽到! – Sam