将控制台输出重定向到 Java 中的字符串

2022-08-31 12:33:50

我有一个方法,其返回类型为void,它直接在控制台上打印。

但是,我需要字符串中的输出,以便我可以对其进行处理。

由于我无法对具有返回类型的方法进行任何更改,因此我必须将该输出重定向到String。void

如何在Java中重定向它?


答案 1

如果函数正在打印到 ,则可以通过使用要更改为转到您提供的方法来捕获该输出。如果创建连接到 的 ,则可以将输出捕获为 .System.outSystem.setOutSystem.outPrintStreamPrintStreamByteArrayOutputStreamString

例:

// Create a stream to hold the output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
// IMPORTANT: Save the old System.out!
PrintStream old = System.out;
// Tell Java to use your special stream
System.setOut(ps);
// Print some output: goes to your special stream
System.out.println("Foofoofoo!");
// Put things back
System.out.flush();
System.setOut(old);
// Show what happened
System.out.println("Here: " + baos.toString());

此程序仅打印一行:

Here: Foofoofoo!

答案 2

下面是一个名为 ConsoleOutputCapturer 的实用程序类。它允许输出转到现有控制台,但在幕后继续捕获输出文本。您可以使用启动/停止方法控制要捕获的内容。换句话说,调用 start 开始捕获控制台输出,完成捕获后,您可以调用 stop 方法,该方法返回一个 String 值,该值保存开始-停止调用之间时间窗口的控制台输出。但是,此类不是线程安全的。

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

public class ConsoleOutputCapturer {
    private ByteArrayOutputStream baos;
    private PrintStream previous;
    private boolean capturing;

    public void start() {
        if (capturing) {
            return;
        }

        capturing = true;
        previous = System.out;      
        baos = new ByteArrayOutputStream();

        OutputStream outputStreamCombiner = 
                new OutputStreamCombiner(Arrays.asList(previous, baos)); 
        PrintStream custom = new PrintStream(outputStreamCombiner);

        System.setOut(custom);
    }

    public String stop() {
        if (!capturing) {
            return "";
        }

        System.setOut(previous);

        String capturedValue = baos.toString();             

        baos = null;
        previous = null;
        capturing = false;

        return capturedValue;
    }

    private static class OutputStreamCombiner extends OutputStream {
        private List<OutputStream> outputStreams;

        public OutputStreamCombiner(List<OutputStream> outputStreams) {
            this.outputStreams = outputStreams;
        }

        public void write(int b) throws IOException {
            for (OutputStream os : outputStreams) {
                os.write(b);
            }
        }

        public void flush() throws IOException {
            for (OutputStream os : outputStreams) {
                os.flush();
            }
        }

        public void close() throws IOException {
            for (OutputStream os : outputStreams) {
                os.close();
            }
        }
    }
}