• java Process在windows的使用汇总(转)


    最常用的是ant(java工程中流行),maven,及通用的exec(只要有shell脚本如.sh,.bat,.exe,.cmd等).而其实前两者不容易出错,后者却遇到了以下问题:
    Caused by: java.io.IOException: Cannot run program "DailyBuild.bat"...java.io.IOException: CreateProcess error=2

    而现在的问题是觉得<exec>节点的workingdir属性设置正确,而command 属性也是指向了要执行的批处理文件"DailyBuild.bat",为什么还要报错呢?于是先把相对路径全改成了绝对,发现不行;又试了把workingdir属性去掉,把command属性写全路径(因为工作目录去掉了,所以一定得写全),发现能运行了,只是报错,因为引用不对了. 这样一来,问题明了了,补回workingdir属性,运行成功! 
    得出这样的结论,workingdir属性会让人产生错觉使你在command属性中不再写这个所谓重复的工作目录部分了,而实际上恰恰要写全路径.效果可能类似这样的:)
    <exec
                 workingdir="projects/${project.name}/deploy/build/"
                command="projects/${project.name}/deploy/build/DailyBuild.bat"
                errorstr="build failed"/> 

    http://www.verydemo.com/demo_c128_i15102.html

    在执行bat时如果将commnd 改为 cmd /c DailyBuild.bat也可以。

    Runtime.getRuntime().exec()方法执行bat时,如果bat没有按预期执行,可以使用如下形式:

    Process p = Runtime.getRuntime().exec("cmd /c start D:\catalina.bat start", null, new File("D:\apache-tomcat-6.0.35"));
    http://www.oschina.net/question/927474_84637


    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那样执行较为复杂的命令. 比如, 输出流的重定向, 如:
    他会立即返回, 不会去执行. 但是我们可以这样做, 能够完成于cmd中一样的工作:
    其中 /c 就是"执行后面字符串的命令". 这样就OK了,但同时还是要注意"错误输出流"的问题,依然要单开一个线程读取.否则一样会阻塞的.

    http://www.xuebuyuan.com/695058.html

    3、Runtime.getRuntime().exec() 路基中含有空格,如下: 

    Runtime.getRuntime().exec("cmd.exe /c D:\Program  Files\tece2.1\tececode\updateprogram\updateProgram.exe");

    这样讲无法执行,需要在空格的前后加上双引号,而不是在整个路径的前后加双引号,如下: 

    Runtime.getRuntime().exec("cmd.exe /c D:\Program" "Files\tece2.1\tececode\updateprogram\updateProgram.exe");

    或者使用替换方式:

    String  commandStr="cmd.exe /c"+" " +realPath.realTomcatPath.replace(" ", "" "");  
    Runtime.getRuntime().exec(commandStr);

    http://flyeagle.iteye.com/blog/406487


    cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭.hi://apps;c dir 是执行完dir命令后关闭命令窗口,原窗口不会关闭;k start dir 会打开一个新窗口后执行dir指令://apps:

    还可以设置工作目录,对执行与工作目录相关的批处理文件是有用的。
    File dir = new File("E:\Product");
    Process process = Runtime.getRuntime().exec("E:\Product\copy.bat",null,dir);
    http://blog.sina.com.cn/s/blog_3d731e9001000ajm.html

    今天使用nio编写一个类似ssh的网络客户端,在执行process的时候,出现了一个让人很头疼的bug,废话不说,上代码:

    public static void main(String[] args)throws Exception {
            Process process=Runtime.getRuntime().exec("cmd /c tree");
            int status=process.exitValue();
            System.out.println(status);
            BufferedReader reader=new BufferedReader(new   InputStreamReader(process.getInputStream()));
            String line=null;
            while((line=reader.readLine())!=null) {
                System.out.println(line);
            }
            
            BufferedReader error=new BufferedReader(new InputStreamReader(process.getErrorStream()));
            while((line=error.readLine())!=null) {
                System.out.println(line);
            }
        }

    在process后面立即调用后

     int status=process.exitValue();

    出现了
    java.lang.IllegalThreadStateException: process has not exited
    at java.lang.Win32Process.exitValue(Native Method)

    异常,后来一百度发现,jdk实现process时,调用外部命令不是同步的调用,而是异步执行。所以tree命令还没有执行成功就返回,jdk抛出异常

    后来想了一招,就是不管执行如何,先去读取process的InputStream和ErrorInputStream,也就是说

    不管外部命令执行的正确与否,都先去执行一次。

    //读取正确执行的返回流 
    BufferedReader info=new BufferedReader(new InputStreamReader(executor.getInputStream()));
     while((line=info.readLine())!=null) {
                infoMsg.append(line).append("
    ");
          }
    
    //读取错误执行的返回流
     BufferedReader error=new BufferedReader(new InputStreamReader(executor.getErrorStream()));
     while((line=error.readLine())!=null) {
                errorMsg.append(line).append("
    ");
        }
    
    //调用exitValue返回值
     responseCode=executor.exitValue();

    这个时候,再调用exitValue()方法就不会出错了

      这是一个具体的实例

            int responseCode=0;
            StringBuilder infoMsg=new StringBuilder();
            StringBuilder errorMsg=new StringBuilder();
            String line=null;
            
            String cmd=Util.isWindows()?("cmd /c "+command):(command);
            System.err.println("command is "+cmd);
            Process executor=Runtime.getRuntime().exec(cmd);
            
            BufferedReader info=new BufferedReader(new InputStreamReader(executor.getInputStream()));
            BufferedReader error=new BufferedReader(new InputStreamReader(executor.getErrorStream()));
            while((line=info.readLine())!=null) {
                infoMsg.append(line).append("
    ");
            }
            
            while((line=error.readLine())!=null) {
                errorMsg.append(line).append("
    ");
            }
            responseCode=executor.exitValue();

    http://kingj.iteye.com/blog/1420586

  • 相关阅读:
    英语影视台词---三、Cinema Paradiso
    英语影视台词---二、Inception
    智课雅思短语---二、exert positive/ negative effects on…
    MVC 编程模型及其变种
    四:redis的sets类型
    HDU 2048 号码塔(DP)
    删除句子UITableView额外的底线和切割线
    css+html菜单适应性学习的宽度
    删RAC中间ASM和LISTENER 资源的正确方法
    联合县城市,采用ajax,而使用ul模拟select下拉
  • 原文地址:https://www.cnblogs.com/softidea/p/4285266.html
Copyright © 2020-2023  润新知