龙哥网

龙哥网

Java中Process类的使用与注意事项说明_java(java process类)
2022-03-01

目录
  • Process类的使用与注意事项说明
    • 1、在项目开发中
    • 2、在这里就需要认识一下process类
    • 3、来说说今天业务需求[waitfor()]:
    • 4、前不久遇到一个奇怪的问题就是ajax调用没有返回值
  • java的process实例讲解

    Process类的使用与注意事项说明

    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){}  
                       }  
            }
    

    java的process实例讲解

    package cn.itcast.process;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    
    public class ProcessTest implements Runnable{
     private Process process = null; 
     public ProcessTest() {
      try {
       process = Runtime.getRuntime().exec("java MyTest");
       new Thread(this).start();
       
      } catch (IOException e) {
       e.printStackTrace();
      }
     }
      
     public static void main(String[] args)  {
      ProcessTest processTest = new ProcessTest();
      processTest.send();
      
     }
     public void send()
     {
      OutputStream outputStream = process.getOutputStream();
      while(true)
      {
       try {
        outputStream.write("this is good\r\n".getBytes());
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }
     }
     public void run() {
      InputStream inputStream = process.getInputStream();
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
      String str = null;
      try {
       while(true)
       {
        str = bufferedReader.readLine();
        System.out.println(str);
       }   
      } catch (IOException e) {
       e.printStackTrace();
      }    
     }
    }
    

    理解下面这句话就能更加容易的理解上面的代码

    在java程序中可以用Process类的实例对象来表示子进程,子进程的标准输入和输出不在连接到键盘和显示器,而是以管道流的形式连接到父进程的 一个输出流和输入流对象上-à好好理解这句代码就能看懂那个程序。

    免责声明
    本站部分资源来源于互联网 如有侵权 请联系站长删除
    龙哥网是优质的互联网科技创业资源_行业项目分享_网络知识引流变现方法的平台为广大网友提供学习互联网相关知识_内容变现的方法。