Runtime.getRuntime().exec()执行阻塞问题解决

ava中用Runtime.getRuntime().exec() 调用外部程序, 获取"标准输出流", 老是阻塞. 在网上找了找, 觉得应该是"错误输出流"的问题. 果然, 为"错误输出流"单开一个线程读取之, "标准输出流"就不再阻塞了. 源码如下:

 


  1. /**执行外部程序,并获取标准输出*/  
  2. public static String excuteCmd_multiThread(String[] cmd,String encoding)  
  3.     {  
  4.         BufferedReader bReader=null;  
  5.         InputStreamReader sReader=null;  
  6.         try  
  7.         {  
  8.                Process p = Runtime.getRuntime().exec(cmd);  
  9.   
  10.                /*为"错误输出流"单独开一个线程读取之,否则会造成标准输出流的阻塞*/  
  11.                Thread t=new Thread(new InputStreamRunnable(p.getErrorStream(),"ErrorStream"));  
  12.                t.start();  
  13.   
  14.                /*"标准输出流"就在当前方法中读取*/  
  15.                BufferedInputStream bis = new BufferedInputStream(p.getInputStream());  
  16.   
  17.                if(encoding!=null && encoding.length()!=0)  
  18.                {  
  19.                     sReader = new InputStreamReader(bis,encoding);//设置编码方式  
  20.                }  
  21.                else  
  22.                {  
  23.                    sReader = new InputStreamReader(bis,"GBK");  
  24.                }  
  25.                bReader=new BufferedReader(sReader);  
  26.   
  27.                StringBuilder sb=new StringBuilder();  
  28.                String line;  
  29.   
  30.                while((line=bReader.readLine())!=null)  
  31.                {  
  32.                    sb.append(line);  
  33.                    sb.append("/n");  
  34.                }  
  35.   
  36.                bReader.close();  
  37.                p.destroy();  
  38.                return sb.toString();  
  39.         }  
  40.         catch(Exception e)  
  41.         {  
  42.             e.printStackTrace();  
  43.             return ErrorString;  
  44.         }  
  45.         finally  
  46.         {  
  47.         }  
  48.     }  
  49.   
  50. /**读取InputStream的线程*/  
  51. class InputStreamRunnable implements Runnable  
  52. {  
  53.     BufferedReader bReader=null;  
  54.     String type=null;  
  55.     public InputStreamRunnable(InputStream is, String _type)  
  56.     {  
  57.         try  
  58.         {  
  59.             bReader=new BufferedReader(new InputStreamReader(new BufferedInputStream(is),"UTF-8"));  
  60.             type=_type;  
  61.         }  
  62.         catch(Exception ex)  
  63.         {  
  64.         }  
  65.     }  
  66.     public void run()  
  67.     {  
  68.         String line;  
  69.         int lineNum=0;  
  70.   
  71.         try  
  72.         {  
  73.             while((line=bReader.readLine())!=null)  
  74.             {  
  75.                 lineNum++;  
  76.                 //Thread.sleep(200);  
  77.             }  
  78.             bReader.close();  
  79.         }  
  80.         catch(Exception ex)  
  81.         {  
  82.         }  
  83.     }  
  84. }  

 

另外, Runtime.getRuntime().exec() 还有一些局限性, 就是无法像cmd那样执行较为复杂的命令. 比如, 输出流的重定向, 如:

[java]  view plain copy
  1. Runtime.getRuntime.exec("XX.exe YY.doc > ZZ.txt");  

 

他会立即返回, 不会去执行. 但是我们可以这样做, 能够完成于cmd中一样的工作:

[c-sharp]  view plain copy
  1. Runtime.getRuntime.exec("cmd /c XX.exe YY.doc > ZZ.txt");  

 

其中 /c 就是"执行后面字符串的命令". 这样就OK了,但同时还是要注意"错误输出流"的问题,依然要单开一个线程读取.否则一样会阻塞的.


原文:http://blog.csdn.net/dysj4099/article/details/5985596

你可能感兴趣的:(system)