一 java 调用外部命令的方式

一般调用的方式如下:

  1. Process pid = null
  2. String[] cmd = { "/bin/sh""-c""shellCommand" };      
  3. pid = Runtime.getRuntime().exec(cmd);                
  4. bufferedReader = new BufferedReader(new InputStreamReader(pid.getInputStream()), 1024); 
  5.                  
  6. String line = null
  7. while (bufferedReader != null && (line = bufferedReader.readLine()) != null) { 
  8.         System.out.println(line); 
  9. }    
  10.                      
  11. pid.waitFor();   
  12. int success = pid.exitValue(); 
  13. pid.destroy();// to kill the subprocess 

说明:

 
二 解决process.waitFor(),导致主线程block的状态
原因一般为进程有标准输出和错误输出,一般只操作标准输出,如果有错误输出就会导致主线程阻塞。
 
<1>使用ProcessBuilder类,设置redirectErrorStream(boolean redirectErrorStream)方法,让错误输出流与标准输出合起来,之后就可以在主线程中来process.getInputStream()就可以获得所有的输出。
 
  1. String[] cmd = { "/bin/sh""-c", shellCommand }; 
  2. Process pid = null
  3. ProcessBuilder build = new ProcessBuilder(cmd); 
  4. build.redirectErrorStream(true); 
  5. pid=build.start(); 
  6. bufferedReader = new BufferedReader(new InputStreamReader(pid.getInputStream()), 1024); 
 
<2>启动其他线程清理输出
写个专门清理输出的线程,然后在调用waitFor之前,启动两个线程负责标准输出与错误输出。
例如:
  1. class StreamGobbler extends Thread 
  2.  { 
  3.      InputStream is; 
  4.      String type; 
  5.       
  6.      StreamGobbler(InputStream is, String type) 
  7.      { 
  8.          this.is = is; 
  9.          this.type = type; 
  10.      } 
  11.       
  12.      public void run() 
  13.      { 
  14.          try 
  15.          { 
  16.              InputStreamReader isr = new InputStreamReader(is); 
  17.              BufferedReader br = new BufferedReader(isr); 
  18.              String line=null
  19.              while ( (line = br.readLine()) != null
  20.                  System.out.println(type + ">" + line);     
  21.              } catch (IOException ioe) 
  22.                { 
  23.                  ioe.printStackTrace();   
  24.                } 
  25.      } 
  26.  } 

使用方法:

 

  1. Process proc = Runtime.getRuntime().exec("java com.zjdw.course.Assign " + path); 
  2.  
  3. new StreamGobbler(proc.getInputStream(),"INFO").start(); 
  4.  
  5. new StreamGobbler(proc.getErrorStream(),"ERROR").start(); 
  6.  
  7. int status = proc.waitFor();