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

本文介绍如何使用Java的Runtime.getRuntime().exec()方法调用外部程序,并通过为错误输出流创建独立线程来避免标准输出流的阻塞现象。此外,还提供了处理复杂命令的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


转载地址:   http://blog.youkuaiyun.com/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了,但同时还是要注意"错误输出流"的问题,依然要单开一个线程读取.否则一样会阻塞的.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值