web-dev-qa-db-ja.com

コンソール出力をjavaの文字列にリダイレクトします

戻り値の型はVOIDの関数が1つあり、コンソールに直接印刷します。

ただし、作業できるように、文字列での出力が必要です。

私は戻り値の型が無効な関数で変更を加えることができないので、その出力を文字列にリダイレクトする必要があります。

JAVAでリダイレクトするにはどうすればよいですか?

Stdoutを文字列にリダイレクトすることに関して多くの質問がありますが、ユーザーから取得した入力のみをリダイレクトし、一部の関数の出力はリダイレクトしません...

55
SRK

関数がSystem.outに出力する場合、System.setOutメソッドを使用してSystem.outを変更し、提供されたPrintStreamに移動することにより、その出力をキャプチャできます。 PrintStreamに接続されたByteArrayOutputStreamを作成すると、出力をStringとしてキャプチャできます。

例:

// 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());

このプログラムは1行だけを出力します。

Here: Foofoofoo!
103

ConsoleOutputCapturerという名前のユーティリティクラスを次に示します。出力は既存のコンソールに送られますが、舞台裏では出力テキストをキャプチャし続けます。 start/stopメソッドを使用して、キャプチャする対象を制御できます。つまり、startを呼び出してコンソール出力のキャプチャを開始します。キャプチャが完了すると、start-stop呼び出し間の時間ウィンドウのコンソール出力を保持する文字列値を返すstopメソッドを呼び出すことができます。ただし、このクラスはスレッドセーフではありません。

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();
            }
        }
    }
}
20