Java捕获进程的所有输出并将其记录到文件中

时间:2013-03-23 20:33:48

标签: java process

我正在尝试从java中的应用程序记录所有输出,并且由于某种原因它只捕获前2行,我知道应用程序输出的内容比这更多,这是我的代码

logOut = new BufferedWriter(new FileWriter("WebAdmin.log"));

        ProcessBuilder procBuild = new ProcessBuilder(
            "java", "-Xmx1G", "-Xms512M", "-jar", "TekkitServer\\Tekkit.jar", "nogui", "-nojline"
        );
        server = procBuild.start();

        inputStream = new BufferedReader(new InputStreamReader(server.getInputStream()));
        errorStream = new BufferedReader(new InputStreamReader(server.getErrorStream()));
        outputStream = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));

        String line = "";

        while(!shutdown){
            while((line = inputStream.readLine()) != null){
                logOut.write(line+"\r\n");
                logOut.flush();
                System.out.println(line);
            }
            System.out.println("checking error stream");
            while((line = errorStream.readLine()) != null){
                logOut.write(line+"\r\n");
                logOut.flush();
                System.out.println(line);
            }
        }

        System.out.println("Stoped Reading");
        logOut.close();
        server.destroy();

我甚至没有在我的控制台中看到“检查错误流”。

3 个答案:

答案 0 :(得分:2)

我认为不需要外部,而是从输出流块读取,直到有一些数据可用,如果子流程结束,你将获得null而内部将会打破。您也可以使用ProcessBuilder的{​​{3}}将stderr重定向到stdout,这样您就可以在一个循环中捕获它们。

答案 1 :(得分:1)

您必须在自己的线程中读取stdout和stderr流。否则,您将获得各种阻塞情况(取决于操作系统和输出模式)。

如果将错误流与输出流(redirectErrorStream(true))合并,则可以使用单个(附加)后台线程。当您使用redirectOutput(File)(或inheritIO)时,可以避免这种情况。

答案 2 :(得分:0)

Minecraft服务器中的前两行是STDOUT(在bukkit,tekkit和vanilla上测试过),但其余的都是STDERR,原因是什么。您的应用程序未对errorStream执行任何操作。您可以尝试使用重定向功能:。

ProcessBuilder procBuild = new ProcessBuilder(
        "java", "-Xmx1G", "-Xms512M", "-jar", "TekkitServer\\Tekkit.jar",
        "nogui", "-nojline", "2>&1");

让我知道这是否有效,因为这可能是一个只有抨击的技巧。