System.out to a file in java
You can use the output stream redirector that is supported by the Windows command line, *nix shells , e.g.
java -jar myjar.jar > output.txt
Alternatively, as you are running the app from inside the vm, you could redirect System.out
from within java itself. You can use the method
System.setOut(PrintStream ps)
Which replaces the standard output stream, so all subsequent calls to System.out go to the stream you specify. You could do this before running your wrapped application, e.g. calling System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt"))));
If you are using a wrapper that you can't modify, then create your own wrapper. So you have FEST wrapper -> stream redirector wrapper -> tested app.
For example, you can implement a simple wrapper like this:
public class OutputRedirector
{
/* args[0] - class to launch, args[1]/args[2] file to direct System.out/System.err to */
public static void main(String[] args) throws Exception
{ // error checking omitted for brevity
System.setOut(outputFile(args(1));
System.setErr(outputFile(args(2));
Class app = Class.forName(args[0]);
Method main = app.getDeclaredMethod("main", new Class[] { (new String[1]).getClass()});
String[] appArgs = new String[args.length-3];
System.arraycopy(args, 3, appArgs, 0, appArgs.length);
main.invoke(null, appArgs);
}
protected PrintStream outputFile(String name) {
return new PrintStream(new BufferedOutputStream(new FileOutputStream(name)), true);
}
}
You invoke it with 3 additional params - the Main class to run, and the output/error directs.
Java writing to File or System.out
What you're trying to accomplish, is to treat the fileoutput and the consoleoutput the same. This is possible, because System.out
is a PrintStream
, and you can create a PrintStream
for a file like this
new PrintStream(yourFile)
or insert a BufferedOutputStream
in between
new PrintStream(new BufferedOutputStream(new FileOutputStream(yourFile))).
Note that this is not needed, because PrintStream
does buffer its output itself.
I would create a variable (global or not), representing the current output.
This might be a PrintStream
, either System.out
, or a PrintStream
around a FileOutputStream
, whatever you desire. You would then pass this stream to the write method or call the print methods on it directly.
The advantage is that you can easily switch this without much code modification, you can redirect it wherever you wan't. It's no problem to redirect it to a file and System.out
! You wouldn't get that pure flexibility with the way you're writing the method currently.
You could (not saying you should), also redirect System.out
directly, using System.setOut
. This however is bad style, because it is quite uncommon and might confuse everyone else, if they have not seen the call to System.setOut
.
Writing System.Out.Println into text file
System.out
is a PrintStream
that writes to the standard output. You need to create a FileOutputStream
and decorates it with PrintStream
(or better FileWriter
with PrintWriter
):
File file = new File("C:/file.txt");
FileWriter fw = new FileWriter(file);
PrintWriter pw = new PrintWriter(fw);
pw.println("Hello World");
pw.close();
Also see:
- Which is the best way to create file and write to it in Java.
Show stdout in file and in console (with System.setOut(new PrintStream(new File(output-file.txt))
You could create a PrintWriter
with an OutputStream
that does both writes.
final OutputStream stdOut = System.out;
try {
System.setOut(new PrintStream(new OutputStream() {
private PrintStream ps = new PrintStream(new File("output-file.txt"));
@Override
public void write(int b) throws IOException {
ps.write(b);
stdOut.write(b);
}
@Override
public void flush() throws IOException {
super.flush();
ps.flush();
stdOut.flush();
}
@Override
public void close() throws IOException {
super.close();
ps.close();
// stdOut.close(); // Normally not done
}
}));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Hello, world!");
Write all System.out into a file
What about System.setOut(PrintStream)
? You could insert this call in the initialization part of your program (start-up).
Was previously a commment:
And of course you can do the same with System.err - namely System.setErr(PrintStream), but better to a different file stream.
In detail assuming an autoflushing appending and buffered file stream:
String file = ...;
PrintStream ps =
new PrintStream(true, new BufferedOutputStream(new FileOutputStream(file, true)));
System.setOut(ps);
Writing from System.out.println to a file
Every time you call WriteToFile.write
, it reopens the file for writing, truncating the file's original contents. You should open the file once, in the constructor (and store the PrintWriter
in a field), and add a close
method that calls close
for the PrintWriter
.
On the calling side, do this:
WriteToFile writer = new WriteToFile(filename);
try {
// writer.write(...);
} finally {
writer.close();
}
By having the close
call in a finally
block, you ensure the file is closed even if an exception causes the function to quit early.
How to write console output to a txt file
You need to do something like this:
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
The second statement is the key. It changes the value of the supposedly "final" System.out
attribute to be the supplied PrintStream value.
There are analogous methods (setIn
and setErr
) for changing the standard input and error streams; refer to the java.lang.System
javadocs for details.
A more general version of the above is this:
PrintStream out = new PrintStream(
new FileOutputStream("output.txt", append), autoFlush);
System.setOut(out);
If append
is true
, the stream will append to an existing file instead of truncating it. If autoflush
is true
, the output buffer will be flushed whenever a byte array is written, one of the println
methods is called, or a \n
is written.
I'd just like to add that it is usually a better idea to use a logging subsystem like Log4j, Logback or the standard Java java.util.logging subsystem. These offer fine-grained logging control via runtime configuration files, support for rolling log files, feeds to system logging, and so on.
Alternatively, if you are not "logging" then consider the following:
With typical shells, you can redirecting standard output (or standard error) to a file on the command line; e.g.
$ java MyApp > output.txt
For more information, refer to a shell tutorial or manual entry.
You could change your application to use an
out
stream passed as a method parameter or via a singleton or dependency injection rather than writing toSystem.out
.
Changing System.out
may cause nasty surprises for other code in your JVM that is not expecting this to happen. (A properly designed Java library will avoid depending on System.out
and System.err
, but you could be unlucky.)
Related Topics
Jtable How to Refresh Table Model After Insert Delete or Update the Data
How to Add Hyperlink in Jlabel
El Access a Map Value by Integer Key
How to Exclude All Instances of a Transitive Dependency When Using Gradle
How to Find Nth Occurrence of Character in a String
What Causes "Unable to Access Jarfile" Error
What Is the Regex to Extract All the Emojis from a String
Ideal Method to Truncate a String with Ellipsis
Bypass Generatedvalue in Hibernate (Merge Data Not in Db)
Try with Resources VS Try-Catch
Java Jar File: Use Resource Errors: Uri Is Not Hierarchical
H2 In-Memory Database. Table Not Found
"Java.Lang.Outofmemoryerror:Unable to Create New Native Thread"