zjcsuct
Throwable文摘
2016-07-16 05:31
采纳率: 0%
浏览 3.6k

关于java调用cmd执行批处理和获取控制台输出的问题

 package cn.zjcscut.compile.cmd;

import cn.zjcscut.compile.cmd.util.ClassUtils;
import cn.zjcscut.compile.cmd.util.StreamGobbler;
import cn.zjcscut.freemarker.classUtils.ClassLoader;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.*;

/**
 * @author zjc
 * @version 2016/7/15 23:09
 * @function
 */
public class DynamicCompileWithCmd {

    private static final Logger log = LogManager.getLogger(DynamicCompileWithCmd.class);

    private static final String SAVEPATH = ClassLoader.getUserDir() + "/bin/source/";

    private static final String CLASSSUFFIX = ".java";

    private static final String BATSUFFIX = ".bat";

    private String className;

    private String result;

    public void save(String content) {
        className = ClassUtils.getClassNameFromSourceCode(content);
        if (StringUtils.isEmpty(className)) {
            log.error("获取类名失败,估计是类的结构出现异常");
            throw new RuntimeException("class format error,please check it!");
        }

        String realFile = SAVEPATH + className + CLASSSUFFIX;
        File file = new File(realFile);
        if (!file.exists()) {
            file.getParentFile().mkdirs();  //不存在就创建
        }

        BufferedWriter bf = null;
        FileWriter fw = null;
        try {
            fw = new FileWriter(file);
            bf = new BufferedWriter(fw);
            bf.write(content);

            bf.close();
            fw.close();
        } catch (Exception e) {
            log.error("写入源代码生成.java文件失败");
            throw new RuntimeException("create java file failed");
        } finally {
            if (bf != null) {
                try {
                    bf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private String createBatFile(String className) {
        String realFile = SAVEPATH + className + BATSUFFIX;
        File file = new File(realFile);
        if (!file.exists()) {
            file.getParentFile().mkdirs();  //不存在就创建
        }
        String compile = "javac " + className + CLASSSUFFIX + " \n";
        String cd = "cd " + SAVEPATH + " \n";
        String run = "java " + className + " \n";
        BufferedWriter bf = null;
        FileWriter fw = null;
        try {
            fw = new FileWriter(file);
            bf = new BufferedWriter(fw);
            bf.write(cd + compile + run);
            bf.close();
            fw.close();
            return realFile;
        } catch (Exception e) {
            log.error("写入bat文件失败");
            throw new RuntimeException("create bat file failed");
        } finally {
            if (bf != null) {
                try {
                    bf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private static Process process;//执行子进程

    public String execute(String content) {
        save(content);
        String batName = createBatFile(className);
        Runtime runtime = Runtime.getRuntime();
        BufferedWriter bw = null;
        try {


//          Thread.sleep(1000);  //防止cmd.exe程序未启动,当然也可以直接使用javac命令
//          bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
//          String compile = "javac " + SAVEPATH + className + CLASSSUFFIX + " \n";
//          String run ="java " + SAVEPATH + className + " \n";


            long startFreeMemory = runtime.freeMemory();  //记录开始执行命令前的空闲内存
            long startCurrentTime = System.currentTimeMillis();
//          bw.write("java " + SAVEPATH + className + " \n");
//          bw.write(compile + " & " + run);
//          bw.flush();
//          bw.close();
//          "cmd.exe /C start /b "
            process = runtime.exec("cmd.exe /C start /b " + batName);

            //合并流
            SequenceInputStream sis = new SequenceInputStream(process.getInputStream(),process.getErrorStream());
            InputStreamReader isr = new InputStreamReader (sis, "GBK");
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while (null != ( line = br.readLine () ))
            {
                System.out.println (line);
            }
            process.destroy ();
            br.close ();
            isr.close ();

            process.waitFor();
            int sign = process.exitValue();
            if (sign == 0) {
                System.out.println("执行成功");
            } else {
                System.out.println("执行失败");
            }

//          StreamGobbler outGobbler = new StreamGobbler(process.getInputStream(), "STDOUT");
//          Thread thread1 = new Thread(outGobbler);
//          thread1.start();

//          new Thread(new Runnable() {
//              @Override
//              public void run() {
//                  try {
//
//                      String s = null;
//                      BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
//                      while ((s = br.readLine()) != null) {
//                          System.out.println(s);
//                          result += s;
//                      }
//                  } catch (java.lang.Exception e) {
//                      e.printStackTrace();
//                  }
//              }
//          }).start();
//
//          new Thread(new Runnable() {
//              @Override
//              public void run() {
//                  try {
//
//                      String s = null;
//                      BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
//                      while ((s = br.readLine()) != null) {
//                          System.out.println("error -- " + s);
//                      }
//                  } catch (java.lang.Exception e) {
//                      e.printStackTrace();
//                  }
//              }
//          }).start();


//          StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");
//          Thread thread = new Thread(errorGobbler);
//          thread.start();
//          Thread thread = new Thread(new RuntimeResultThread());
//          thread.start();

//          String s = null;
//          BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
//          while ((s = br.readLine()) != null) {
//              System.out.println(s);
//              result += s;
//          }
//
//          br.close();
//          System.out.println(batName);
//          InputStream in =  process.getInputStream();
//
//          int c;
//          while ((c = in.read()) != -1) {
//              System.out.print("输出---" + c);//如果你不需要看输出,这行可以注销掉
//          }
//          in.close();



            //获取控制台输出结果
//          Thread thread = new Thread(new RuntimeResultThread());
//          thread.start();
            long endCurrentTime = System.currentTimeMillis();
            long endFreeMemory = runtime.freeMemory();
            double useMemory = (startFreeMemory - endFreeMemory) / 1024;
            long useTime = endCurrentTime - startCurrentTime;

            result += "\n\ncost time : " + useTime + " ms" + ", cost memory : " + useMemory + " mb";
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private class RuntimeResultThread implements Runnable {

        @Override
        public void run() {
            BufferedReader br = null;
            String content = null;
            try {
                br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
                while ((content = br.readLine()) != null) {
                    System.out.println("content" + content);
                    result += content;
                }
                br.close();
            } catch (Exception e) {
                log.error("获取控制台输出失败");
                e.printStackTrace();
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

上边的代码是为了实现动态编译和执行输入的java源码,原理是先把.java和bat文件输出到工作目录下的一个文件夹,调用cmd编译.java文件,再执行.class。现在出现一个问题,就是获取控制台输出的时候总是阻塞,google这个问题说是process的getErrorStream缓冲没有清空,导致一直阻塞,需要使用多线程操作,但是用了多线程发现,process的getInputStream部分信息丢失了。
图片说明

想请教有什么解决方法 ?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

相关推荐