博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中Process类的使用与注意事项
阅读量:3576 次
发布时间:2019-05-20

本文共 6231 字,大约阅读时间需要 20 分钟。

(1)在项目开发中,经常会遇到调用其它程序功能的业务需求,在java中通常有两种实现方法

Runtime runtime = Runtime.getRuntime();Process p = runtime.exec(cmd);
Process p=new ProcessBuilder(cmd).start();

(2)在这里就需要认识一下process类:process是一个抽象的类,它包含6个抽象的方法

abstract public OutputStream getOutputStream();abstract public InputStream getInputStream();abstract public InputStream getErrorStream();abstract public int waitFor() throws InterruptedException;abstract public int exitValue();abstract public void destroy();

process类提供获取子进程的输入流、子进程的输出流、子进程的错误流、等待进程完成、检查进程的推出状态以及销毁进程的方法;在这里需要提及的是创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中。

(3)来说说今天业务需求[waitfor()]:我需要在linux下首先将一个文件copy到指定的文件夹下面,之后需要将该文件夹下面的文件加入指定的jar中,那么问题就来了,必须保证其先后顺序,也就书说再执行第二个命令的时候第一个命令必须完成。

public void cmd(String cmd){        try {            Process ps= Runtime.getRuntime().exec(cmd);         } catch (Exception e) {            logger.info(e.getMessage(),e);        }    }

main函数如下:

public static void main(String[] args){     String copy="cp -rf "+source+" "+target;     String jar="jar -uvf "+jar+" "+file;     cmd(copy);     cmd(jar);}

但是结果是新生成的jar中压根没有新加入的文件,但是文件确实copy到了指定的文件夹中,也就是谁两个命令都执行了,问题的关键就是“异步”,这时候需要waitFor()的介入

public void cmd(String cmd){        try {            Process ps= Runtime.getRuntime().exec(cmd);             ps.waitFor();        } catch (Exception e) {            logger.info(e.getMessage(),e);        }    }

那么问题就解决了!

(4)前不久遇到一个奇怪的问题就是ajax调用没有返回值,我在service中实现了process的调用。

String[] commands = { commandGenerate,commandPublish};        PrintWriter printWriter = response.getWriter();        for (String comm : commands) {            Runtime runtime = Runtime.getRuntime();            try {                logger.info("command is :{}",comm);                Process process = runtime.exec(comm, null, null);                BufferedInputStream inputStream = new BufferedInputStream(                        process.getInputStream());                BufferedReader bufferedReader = new BufferedReader(                        new InputStreamReader(inputStream));                String line;                while (bufferedReader.read() != -1) {                    line = bufferedReader.readLine();                    System.out.println(line);                }                bufferedReader.close();                inputStream.close();                printWriter.println("success");            } catch (IOException e) {                logger.error(e.getMessage(), e);                printWriter.println(e.getMessage());            }        }        printWriter.flush();        printWriter.close();

对应的controller为:

State state = new State();        String message="";        try {            message = missionService.syntax(taskName, response);        } catch (InterruptedException e) {            e.printStackTrace();        }        state.setSuccess(true);        state.setMessage(message.trim());        return state;

打印state.getMessage()确实可以获得值,但是state返回就是空,刚开始以为是ajax的timeout时间的问题:修改了ajax的timeout时间仍然不行;将message直接赋值,然thread等待20s,结果是可以返回的,所以问题最终定为于service的这段实现。

原因分析:在上面提及了,process创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中,如果该可执行程序的输入、输出或者错误输出比较多的话,而由于运行窗口的标准输入、输出等缓冲区有大小的限制,则可能导致子进程阻塞,甚至产生死锁,其解决方法就是在waitfor()方法之前读出窗口的标准输出、输出、错误缓冲区中的内容。

for (String comm : commands) {            logger.info("the comm time is:"+new Date().getTime()+" the comm is:"+comm);            Runtime runtime = Runtime.getRuntime();            Process p=null;            try {                   p = runtime.exec(comm ,null,null);                          final InputStream is1 = p.getInputStream();                    final InputStream is2 = p.getErrorStream();                   new Thread() {                      public void run() {                         BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));                          try {                              String line1 = null;                              while ((line1 = br1.readLine()) != null) {                                    if (line1 != null){                                      logger.info("p.getInputStream:"+line1);                                      if(line1.indexOf("syntax check result:")!=-1){                                          builder.append(line1);                                      }                                  }                                }                          } catch (IOException e) {                               e.printStackTrace();                          }                          finally{                               try {                                 is1.close();                               } catch (IOException e) {                                  e.printStackTrace();                              }                            }                          }                       }.start();                     new Thread() {                         public void  run() {                          BufferedReader br2 = new  BufferedReader(new  InputStreamReader(is2));                             try {                                String line2 = null ;                                while ((line2 = br2.readLine()) !=  null ) {                                     if (line2 != null){                                  }                               }                              } catch (IOException e) {                                    e.printStackTrace();                             }                             finally{                               try {                                   is2.close();                               } catch (IOException e) {                                   e.printStackTrace();                               }                             }                          }                         }.start();                                                                      p.waitFor();                        p.destroy();                       } catch (Exception e) {                              try{                                  p.getErrorStream().close();                                  p.getInputStream().close();                                  p.getOutputStream().close();                                  }                               catch(Exception ee){}                     }          }

转载地址:http://dmpgj.baihongyu.com/

你可能感兴趣的文章
多对多的映射关系和级联
查看>>
金总公司的网络计划
查看>>
hibernate查询方式
查看>>
hibernate抓取策略(关联级别的延迟加载)
查看>>
DNS_PROBE_FINISHED_NXDOMAIN
查看>>
dom4j解析节点元素的crud和xpath
查看>>
初识Struts
查看>>
多线程打印A12Z34。。。
查看>>
strutsc踩过的坑
查看>>
maven安装和使用踩坑
查看>>
第一次紧张刺激的面试
查看>>
咕泡笔记导读篇
查看>>
eclipse安装maven和简单使用
查看>>
关于交往所思
查看>>
jdbc的封装
查看>>
数据库存入数据变为???
查看>>
实现数据库源的几种方式和开源数据源的使用
查看>>
元数据的获取和 数据库读写操作封装
查看>>
java文件的上传和下载(细节问题)
查看>>
DBUtils框架QueryRunner的 使用
查看>>