当批处理的输出太大时,Process.getErrorStream()不起作用

时间:2013-11-29 22:46:04

标签: java batch-file

static String getTime(String command) throws IOException, Throwable{
    try{
        String completeComm=Userdir+"\\timer.bat";
        Process p=Runtime.getRuntime().exec("cmd /c "+completeComm+" "+command+" --batch");

        BufferedReader reader=new BufferedReader (new InputStreamReader(p.getInputStream()));       

        LineIterator l=IOUtils.lineIterator(reader);            
        try {
            while (l.hasNext()) {
                String line = l.nextLine();
                System.out.println(line);
                ...
                }
            }
        } finally {
            LineIterator.closeQuietly(l);
        }

        BufferedReader Ereader=new BufferedReader (new InputStreamReader(p.getErrorStream()));
        LineIterator El=IOUtils.lineIterator(Ereader);          
        try {
            while (El.hasNext()) {
                String line = El.nextLine();
                System.out.println(line);
                ...
                }
            }
        } finally {
            LineIterator.closeQuietly(El);
        }


    }catch(Exception e){
        JOptionPane.showMessageDialog(null, e.getMessage());
        System.exit(0);
    }
}

我的问题是“p.getStreamError”。只有当我的批处理文件的输出/结果不是数百或数千行时,我才能看到p.getStreamError的ouptut,否则我没有得到任何输出(p.getSTreamError)。

  1. 为什么当我的批次的返回结果/数据很大时,我无法从p.getStreamError获取任何输出?

  2. 当我创建一个jar并运行它时,程序会永远挂起。我调试了它,发现它被卡在“while(El.hasNext())”。为什么程序在通过jar运行时挂起并且与eclipse一起正常工作?

  3. 谢谢!

1 个答案:

答案 0 :(得分:1)

您需要为while循环使用单独的线程。

考虑创建一个实现Runnable的StreamGobbler类,它在其构造函数中使用InputStream,并在其run方法中使用while循环。然后使用这些Gobblers创建线程并让它们继续。

类似的东西:

public class StreamGobbler implements Runnable {
   private static String userdir;
   private String name;
   private LineIterator lineIterator;

   public StreamGobbler(String name, InputStream inStream) {
      this.name = name;
      BufferedReader bufReader = new BufferedReader(new InputStreamReader(
            inStream));
      lineIterator = IOUtils.lineIterator(bufReader);
   }

   @Override
   public void run() {
      try {
         while (lineIterator.hasNext()) {
            String line = lineIterator.nextLine();
            System.out.println(line);
            // ...
         }

      } finally {
         LineIterator.closeQuietly(lineIterator);
      }

   }

   public String getName() {
      return name;
   }
}

然后可以这样使用:

String completeComm = userdir + "\\timer.bat";
Process p = Runtime.getRuntime().exec(
       "cmd /c " + completeComm + " " + command + " --batch");
new Thread(new StreamGobbler("InputStream", p.getInputStream())).start();
new Thread(new StreamGobbler("ErrorStream", p.getErrorStream())).start();