Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java将系统调用输出重定向到文件_Java_Multithreading_Logging_File Io_Iostream - Fatal编程技术网

使用Java将系统调用输出重定向到文件

使用Java将系统调用输出重定向到文件,java,multithreading,logging,file-io,iostream,Java,Multithreading,Logging,File Io,Iostream,当前无法将小型windows批处理控制台的输出重定向到日志文件。我的Java应用程序需要在不等待完成的情况下启动Runtime.exec()调用并记录输出。这是我的日志类: public class BatchThreadLogger extends Thread { private Process process; private String logFilePath; private static final Logger logger = Logger.getLogger(Ba

当前无法将小型windows批处理控制台的输出重定向到日志文件。我的Java应用程序需要在不等待完成的情况下启动Runtime.exec()调用并记录输出。这是我的日志类:

public class BatchThreadLogger extends Thread {
  private Process process;
  private String logFilePath;
  private static final Logger logger = Logger.getLogger(BatchThreadLogger.class);

  public BatchThreadLogger(Process process, String logFilePath) {
    this.process = process;
    this.logFilePath = logFilePath;
  }

  public void run() {
    try {
      // create logging file
      File file = new File(logFilePath);
      file.createNewFile();

      // create a writer object
      OutputStream os = new FileOutputStream(file);
      PrintWriter pw = new PrintWriter(os);

      // catch the process output in an InputStream
      InputStreamReader isr = new InputStreamReader(process.getInputStream());
      BufferedReader br = new BufferedReader(isr);

      // wait for the process to complete
      int processStatus = process.waitFor();

      // redirect the output to the log file
      String line = null;
      while ((line = br.readLine()) != null) {
        pw.println(line);
      }

      // add a small message with the return code to the log
      pw.println("********************************************");
      pw.println("********************************************");
      pw.println("Batch call completed with return status " + processStatus);

      pw.flush();
      os.close();
    }
    catch (IOException e) {
      logger.error("IOException raised during batch logging on file " + logFilePath, e);
    }
    catch (InterruptedException e) {
      logger.error("InterruptedException raised during batch process execution", e);
    }
  }
}
我的电话很简单:

Process process = Runtime.getRuntime().exec(command);
BatchThreadLogger logger = new BatchThreadLogger(process, logFilePath);
logger.start();
我的命令当前正在使用两个参数调用My test.bat。我的测试批次现在只需执行以下操作:

echo "BATCH CALLED WITH PARAMETER %1 AND %2"
exit
但是,我的日志文件仅包含:

********************************************
********************************************
Batch call completed with return status 0
我尝试在将输出重定向到日志文件的代码前后调用
waitFor()
,但没有成功。我总是看到命令被启动的黑屏,但日志中什么都没有


任何帮助都将不胜感激,我遗漏了一些东西,但无法理解您没有从您创建的流程的标准错误中读取的内容

我怀疑一条错误消息正在写入标准错误,因为您只读取标准输出,所以没有发现此错误

我建议您将
Runtime.getRuntime().exec(…)
的用法替换为,使用类似于以下内容:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "test.bat", "One", "Two");
pb.redirectErrorStream(true);
Process process = pb.start();

pb.redirectErrorStream(true)将进程的标准错误重定向到其标准输出,这样您就不必在两个单独的线程中读取两个流(标准输出和标准错误)

您没有读取所创建流程的标准错误

我怀疑一条错误消息正在写入标准错误,因为您只读取标准输出,所以没有发现此错误

我建议您将
Runtime.getRuntime().exec(…)
的用法替换为,使用类似于以下内容:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "test.bat", "One", "Two");
pb.redirectErrorStream(true);
Process process = pb.start();

pb.redirectErrorStream(true)将进程的标准错误重定向到其标准输出,这样您就不必在两个单独的线程中读取两个流(标准输出和标准错误)

我不确定你的答案。我想知道在批处理文件中回显文本如何被视为一个错误,从而指向流程执行的错误流。为了确保这一点,我将
getInputStream()
调用替换为
getErrorStream()
,但它仍然不起作用。。。日志文件中没有任何内容…我还在echo调用后添加了一个随机
ping www.google.ch
,以确保echo输出不会重定向到特殊流或任何类似的技巧。。。日志中仍然没有任何内容。顺便说一句,我发布的代码在Linux上确实有效。关于您的ProcessBuilder主张,我将看看它是否可以轻松替换
Runtime.exec()
调用。我想您可能会在尝试运行不存在或由于权限问题而无法读取的批处理文件时出错。但奇怪的是,没有产出。您是否介意准确地共享
命令中的变量?另外,这部分是什么类型的应用程序(例如命令行、web应用程序、GUI、服务)?当然,命令是
cmd/c start c:/ieu/test.bat spjc010j SPJ500000600001010
。这是从运行在JBoss7下的SessionBean中的Web应用程序启动的。您使用
start
有什么原因吗?您是否尝试过在没有启动的情况下运行命令
start
在单独的命令提示符窗口中运行程序,使用
start
运行的程序的输出将转到这个新窗口,而不是
进程
。我不确定您的答案。我想知道在批处理文件中回显文本如何被视为一个错误,从而指向流程执行的错误流。为了确保这一点,我将
getInputStream()
调用替换为
getErrorStream()
,但它仍然不起作用。。。日志文件中没有任何内容…我还在echo调用后添加了一个随机
ping www.google.ch
,以确保echo输出不会重定向到特殊流或任何类似的技巧。。。日志中仍然没有任何内容。顺便说一句,我发布的代码在Linux上确实有效。关于您的ProcessBuilder主张,我将看看它是否可以轻松替换
Runtime.exec()
调用。我想您可能会在尝试运行不存在或由于权限问题而无法读取的批处理文件时出错。但奇怪的是,没有产出。您是否介意准确地共享
命令中的变量?另外,这部分是什么类型的应用程序(例如命令行、web应用程序、GUI、服务)?当然,命令是
cmd/c start c:/ieu/test.bat spjc010j SPJ500000600001010
。这是从运行在JBoss7下的SessionBean中的Web应用程序启动的。您使用
start
有什么原因吗?您是否尝试过在没有启动的情况下运行命令
start
在单独的命令提示符窗口中运行程序,使用
start
运行的程序的输出将转到此新窗口,而不是
进程