我有一個功能,它的返回類型是VOID,它直接在控制檯上打印。將控制檯輸出重定向到java中的字符串
但是我需要在字符串中的輸出,以便我可以在它上面工作。
由於我不能使用返回類型爲VOID的函數進行任何更改,所以我必須將該輸出重定向到字符串。
如何在JAVA中重定向它?
有關於標準輸出重定向到串了很多問題,但他們只重定向根據用戶拍攝的輸入,而不是某些功能的輸出...
我有一個功能,它的返回類型是VOID,它直接在控制檯上打印。將控制檯輸出重定向到java中的字符串
但是我需要在字符串中的輸出,以便我可以在它上面工作。
由於我不能使用返回類型爲VOID的函數進行任何更改,所以我必須將該輸出重定向到字符串。
如何在JAVA中重定向它?
有關於標準輸出重定向到串了很多問題,但他們只重定向根據用戶拍攝的輸入,而不是某些功能的輸出...
如果該函數打印到System.out
,您可以通過使用捕捉輸出System.setOut
方法將System.out
更改爲您提供的PrintStream
。如果創建連接到ByteArrayOutputStream
的PrintStream
,則可以將輸出捕獲爲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());
這個程序打印只有一行:
Here: Foofoofoo!
下面是名爲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();
}
}
}
}
工作很好,工作很好! – 2016-06-09 12:09:17
真的很好的解決方案,雖然我會建議一點點補充,但是在將它設置爲null之前,在stop()方法的baos流上調用close()方法以釋放所有資源。 – davidgale 2016-07-20 09:43:56
完美的作品! :) – Developer66 2018-01-06 11:26:50
不要忘了,完成後調用System.out.flush(),然後將System.out切換回正常(或更正確的說,前面的)System.out。我看到@Ernest已將其添加到他的代碼中。 – user949300 2012-01-03 05:42:29
另外,不要忘記,這會創建線程問題,不僅僅是針對此方法(您可以通過同步它來解決),而是針對打印到標準輸出的任何其他代碼。 'baos.toString()'很容易就可以''Foofohello worldofoo!'' – yshavit 2012-01-03 06:01:01
@Ernest:得到它謝謝... – SRK 2012-01-05 10:35:54