繁体   English   中英

Java:如何将控制台输出镜像到文件

[英]Java: How to mirror console output to file

我需要用Java监视控制台输出,我尝试了几种不同的方法来检索流式输出,但是我陷入了一些陷阱(循环输出相同的输出,仅捕获一部分输出,丢失输出),并且决定以不同的方式去做。

我正在为流行游戏Minecraft的服务器开发Java插件,并且我需要能够监视其他插件的控制台输出。
我认为,执行此操作的一个好方法是将控制台输出重定向到文件,然后设置一个重复执行的异步任务,该任务检查文件,执行需要执行的任何操作,然后清除文件以获取更多输入。 我想我可以通过简单使用System.setOut(PrintStream stream);来完成此操作。 以及我可以在Google上找到的众多指南之一。

但这是有问题的,这就是为什么我今天在这里问。 我需要控制台输出以像平常一样留在控制台上,因此是“镜像”。 我无法编辑任何插件以在其他地方输出,它只能来自我的Java插件可以执行的操作,而仅此而已。 当然,也许在每次计划检查文件时,我都可以将其全部重新打印回控制台,但这将导致一次打印块,这并不理想。 我希望这是可能的。 谢谢!

编辑:我不认为我完全解释。 “插件”的类由我正在开发的程序运行。 我无法更改类的运行方式,也无法更改其他插件在控制台上的打印方式。 我也不想将控制台输出定向到文件以进行日志记录,该想法只是在解析它时将其保存在临时位置。 理想情况下,我需要将控制台输出的每一行传递给一个函数( parseString(String line) ),该函数根据该行的内容执行操作。 另外,我不明白如何正确地逐行读取流内容,因此,如果有人对如何操作有任何想法,请告诉我。 :)

在更改之前捕获System.out,并使用TeeOutputStream

OutputStream myCaptureStream = ...;
PrintStream original = System.out;
OutptStream outputtee = new TeeOutputStream(originalOut, myCaptureStream);
PrintStream printTee = new PrintStream(outputTee);
System.setOut(printTee);

将输出流(myCaptureStream)转换为输入流

BufferedReader为您提供了readLine方法。

伪代码:

// Feed myCaptureStream to TeeOutputStream
OutputStream myCaptureStream = new PipedOutputStream();

// Prepare to capture data being written to that output stream
InputStream myCaptureAsInputStream = new PipedInputStream(myCaptureStream);
Reader myCaptureReader = new InputStreamReader(myCaptureAsInputStream);
BufferedReader myCaptureBuffered = new BufferedReader(myCaptureReader, 1024);

// This must run on separate reader thread; in spin loop:
myCaptureBuffer.readLine

您可以将System.out和System.err更改为对自己的自定义PrintStream的引用。 该解决方案是跨平台的,与使用平台特定的辅助程序可执行文件(例如tee

System.setOut(PrintStream)的文档

您可以编写自己的PrintStream子类,如下所示:

class MirroringPrintStream extends PrintStream
{
    PrintStream first, second;

    public MirroringPrintStream(PrintStream first, PrintStream second)
    {
        // fail now rather than later
        if (first == null || second == null) throw new NullPointerException();

        this.first = first;
        this.second = second;
    }

    @override
    // methods go here (I do believe there are rather a lot of them, but they will all look the same)
}

然后,您可以使用System.setOut(new MirroringPrintStream(System.out, myLogStream)) ,其中myLogStream是您打开到日志文件的PrintStream。 我不确定这将如何处理附加到其他文件被定期截断的文件,您可能需要尝试一下。

其他所有方法均失败,请访问irc.esper.net,并在#risucraft中进行询问

假设这是对控制台输出的友好接管,为什么不登录到您自己的流并将其镜像到控制台?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM