Runtime.getRuntime().exec() 输出流阻塞的解决方法

来源:互联网 发布:udid授权软件 编辑:程序博客网 时间:2024/05/16 18:24


转载地址:   http://blog.csdn.net/xiaoanian/article/details/5922394


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

/**执行外部程序,并获取标准输出*/public static String excuteCmd_multiThread(String[] cmd,String encoding)    {        BufferedReader bReader=null;        InputStreamReader sReader=null;        try        {               Process p = Runtime.getRuntime().exec(cmd);               /*为"错误输出流"单独开一个线程读取之,否则会造成标准输出流的阻塞*/               Thread t=new Thread(new InputStreamRunnable(p.getErrorStream(),"ErrorStream"));               t.start();               /*"标准输出流"就在当前方法中读取*/               BufferedInputStream bis = new BufferedInputStream(p.getInputStream());               if(encoding!=null && encoding.length()!=0)               {                    sReader = new InputStreamReader(bis,encoding);//设置编码方式               }               else               {                   sReader = new InputStreamReader(bis,"GBK");               }               bReader=new BufferedReader(sReader);               StringBuilder sb=new StringBuilder();               String line;               while((line=bReader.readLine())!=null)               {                   sb.append(line);                   sb.append("/n");               }               bReader.close();               p.destroy();               return sb.toString();        }        catch(Exception e)        {            e.printStackTrace();            return ErrorString;        }        finally        {        }    }/**读取InputStream的线程*/class InputStreamRunnable implements Runnable{    BufferedReader bReader=null;    String type=null;    public InputStreamRunnable(InputStream is, String _type)    {        try        {            bReader=new BufferedReader(new InputStreamReader(new BufferedInputStream(is),"UTF-8"));            type=_type;        }        catch(Exception ex)        {        }    }    public void run()    {        String line;        int lineNum=0;        try        {            while((line=bReader.readLine())!=null)            {                lineNum++;                //Thread.sleep(200);            }            bReader.close();        }        catch(Exception ex)        {        }    }}

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

    Runtime.getRuntime.exec("XX.exe YY.doc > ZZ.txt");  

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

Runtime.getRuntime.exec("cmd /c XX.exe YY.doc > ZZ.txt"); 

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


0 0
原创粉丝点击