Redirect System.out.println
The System class has a setOut
and setErr
that can be used to change the output stream to, for example, a new PrintStream
with a backing File
or, in this case, probably another stream which uses your logging subsystem of choice.
Keep in mind you may well get yourself into trouble if you ever configure your logging library to output to standard output or error (of the infinite recursion type, possibly).
If that's the case, you may want to just go and replace your System.out.print
-type statements with real logging calls.
Redirect System.out.println to log
My suggestion would be to refactor if possible.
For a possible solution, check these similar questions
log4j redirect stdout to DailyRollingFileAppender
Redirect System.out.println to Log4J, while keeping class name information
Redirect System.out and System.err
Just to add to Rick's and Mikhail's solutions, which are really the only option in this scenario, I wanted to give an example of how creating a custom OutputStream can potentially lead to not so easy to detect/fix problems. Here's some code:
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.apache.log4j.Logger;
public class RecursiveLogging {
/**
* log4j.properties file:
*
* log4j.rootLogger=DEBUG, A1
* log4j.appender.A1=org.apache.log4j.ConsoleAppender
* log4j.appender.A1.layout=org.apache.log4j.PatternLayout
* log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
*
*/
public static void main(String[] args) {
// Logger.getLogger(RecursiveLogging.class).info("This initializes log4j!");
System.setOut(new PrintStream(new CustomOutputStream()));
System.out.println("This message causes a stack overflow exception!");
}
}
class CustomOutputStream extends OutputStream {
@Override
public final void write(int b) throws IOException {
// the correct way of doing this would be using a buffer
// to store characters until a newline is encountered,
// this implementation is for illustration only
Logger.getLogger(CustomOutputStream.class).info((char) b);
}
}
This example shows the pitfalls of using a custom output stream. For simplicity the write() function uses a log4j logger, but this can be replaced with any custom logging facility (such as the one in my scenario). The main function creates a PrintStream that wraps a CustomOutputStream and set the output stream to point to it. Then it executes a System.out.println() statement. This statement is redirected to the CustomOutputStream which redirects it to a logger. Unfortunately, since the logger is lazy initialized, it will acquire a copy of the console output stream (as per the log4j configuration file which defines a ConsoleAppender) too late, i.e., the output stream will point to the CustomOutputStream we just created causing a redirection loop and thus a StackOverflowError at runtime.
Now, with log4j this is easy to fix: we just need to initialize the log4j framework before we call System.setOut(), e.g., by uncommenting the first line of the main function. Luckily for me, the custom logging facility I have to deal with is just a wrapper around log4j and I know it will get initialized before it's too late. However, in the case of a totally custom logging facility that uses System.out/err under the cover, unless the source code is accessible, it's impossible to tell if and where direct calls to System.out/err are performed instead of calls to a PrintStream reference acquired during initialization. The only work around I can think of for this particular case would be to retrieve the function call stack and detect redirection loops, since the write() functions should not be recursive.
Redirecting System.out.print(ln) to a textArea
Swing is a single threaded framework, this means that any operation which is run within the context of the Event Dispatching Thread, which is long running in nature or blocks for some reason (like I/O operations), will prevent the EDT from processing new events and update the UI.
See Concurrency in Swing for more details
If you're using something like How to set output stream to TextArea to redirect the System.out
, then you could safely wrap the decryption process in some thing like a SwingWorker
or other Thread
, for example...
public class DecryptWorker extends SwingWorker {
private File[] files;
public DecryptWorker(File[] files) {
this.files = files;
}
@Override
protected Object doInBackground() throws Exception {
if(files[0] != null) {
...
for (int j = 0; j < files.length; j++) {
// SDencryptFiles() has System.out.println()'s in it, but
// no System.out's show in the JScrollPane until after
// SDencryptFiles completes I want then to appear as they
// are executed
SDencryptFiles(String, String, int);
}
}
return null;
}
}
See Worker Threads and SwingWorker for more details...
Redirect console output to string in Java
If the function is printing to System.out
, you can capture that output by using the System.setOut
method to change System.out
to go to a PrintStream
provided by you. If you create a PrintStream
connected to a ByteArrayOutputStream
, then you can capture the output as a String
.
Example:
// 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());
This program prints just one line:
Here: Foofoofoo!
Redirect lots of system.out.println's to a .txt file
The System class has a static method, System.setOut(PrintStream out)
. All you have to do is create your own PrintStream that writes to a file, stuff it into this method and you're all set.
Better less fragile solution: Don't use System.out.printFoo(...) but instead just use a logger, and change the logging levels as it suits your purposes at that time.
Related Topics
Reversing a Linked List in Java, Recursively
When Should I Use File.Separator and When File.Pathseparator
How to Go About Formatting 1200 to 1.2K in Java
Java Date Parsing with Microsecond or Nanosecond Accuracy
Why Equals() Method When We Have == Operator
Why Were Applets Deprecated in Jdk 9
Jvm Takes a Long Time to Resolve Ip-Address for Localhost
How to Create Custom Methods for Use in Spring Security Expression Language Annotations
Can a Java File Have More Than One Class
How to Read PDF Files Using Java
How Do Hashcode() and Identityhashcode() Work at the Back End
Clone() VS Copy Constructor VS Factory Method
Performance of Java Matrix Math Libraries
What Happens When a Duplicate Key Is Put into a Hashmap
Override Java System.Currenttimemillis for Testing Time Sensitive Code