Java System.out to both screen and file simultaneously, and programatically [duplicate] - java

I found the code below from the internet, works but it doesn't write the printed console to omt.txt, it only writes the System.out.println statements after the second catch block.If you run the code once you will understand what I mean.All I want is to write what is on console to the "omt.txt" file that is all...
After some answers, I see that my question wasn't clear, sorry for that.
I want to save console output to omt.txt text file. If on the console "Hello 123" is printed , it should be also in omt.txt file.In other words whatever on the console is printed should be simultaneously written on the om.txt file or can be after the console execution but should be 1-to-1 the same!
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class Wrt_file {
public static void main(String[] args) {
System.out.println("THIS is what I see on the console. but not on TEXT file");
File f = new File("omt.txt");
if(!f.exists())
{
try {
f.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
try {
FileOutputStream fos = new FileOutputStream(f);
PrintStream ps = new PrintStream(fos);
System.setOut(ps);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("THIS is what I see on the text file, but not on CONSOLE");
for (int i=0; i<10; i++){
System.out.println("Testing");
}
}
}

Updated answer after learning that OP wants to duplicate streams
Since you want to write data in both streams try using TeeOutputStream from Apache Commons. Change your code in second try to
try {
FileOutputStream fos = new FileOutputStream(f);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
fos.flush();
}
catch (Throwable t) {
// Ignore
}
}, "Shutdown hook Thread flushing " + f));
//we will want to print in standard "System.out" and in "file"
TeeOutputStream myOut=new TeeOutputStream(System.out, fos);
PrintStream ps = new PrintStream(myOut, true); //true - auto-flush after println
System.setOut(ps);
} catch (Exception e) {
e.printStackTrace();
}
Now results from System.out will also be placed in your file.

The reason is :
The java.lang.System.setOut() method reassigns the "standard" output stream.
so when you use System.out.println it will print only in the text file
So , if you want to print on the text file and on the console , Try this :
   
FileOutputStream fos = new FileOutputStream(f);
    PrintStream ps = new PrintStream(fos);
ps.println("THIS is what I see on the text file, but not on CONSOLE");
System.out.println("THIS is what I see on the text file, but not on CONSOLE");
for (int i = 0; i < 4; i++) {
ps.println("Testing");
System.out.println("Testing");
}

My solution to this problem is to simply define your own PrintStream which overrides the methods you are using:
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class DualStream extends PrintStream {
public PrintStream consoleOutput = null;
public PrintStream fileOutput = null;
public DualStream(final PrintStream consoleOutput, final PrintStream fileOutput) throws FileNotFoundException {
super(fileOutput, true);
this.consoleOutput = consoleOutput;
this.fileOutput = fileOutput;
}
#Override
public void println() {
consoleOutput.println();
super.println();
}
#Override
public void println(final Object output) {
consoleOutput.println(output);
super.println(output);
}
#Override
public void println(final String output) {
consoleOutput.println(output);
super.println(output);
}
#Override
public PrintStream printf(final String output, final Object... variables) {
consoleOutput.printf(output, variables);
super.printf(output, variables);
return this;
}
}
Every method we don't override will default to writting the output to the file only. (To default to console you can switch 1 line in the Constructor or switch both printstreams position in the constructor call)
Now simply define 2 printstreams, one of which will be writting to your file, let's make it a bufferedoutputstream to ensure good performance aswell:
public static void outputFile(final String file) {
PrintStream CombinedOutput = null;
try {
CombinedOutput = new DualStream(System.out, new PrintStream(new BufferedOutputStream(new FileOutputStream(file))));
} catch (final FileNotFoundException e) {
e.printStackTrace();
}
System.setOut(CombinedOutput);
}

In System.java, this is the declaration of the out property:
public final static PrintStream out
You'll see that it can only be one PrintSteam object at a time. So it's either the console or the file, but not both.
At this line, you have effectively re-channelled the destination:
System.setOut(ps);
So your output stops displaying on the console.

Related

Java Input Output Stream can't read the file

I really need help with Java io manipulation of Streams. I don't know why this won't show me the contents of the file. I need to be able to view the text in this binary file "Data.abc" If I can view the contents of this file, i need to create a switch case condition to display it's contents per row / column.
Everytime I run the program, it returns some weird letters and characters like � NAme Address�����
Please help. I'm new to manipulation of streams. Thanks.
package IO_ReadFile;
import java.io.*;
public class ReadFile {
public static void main(String[] args) {
InputStream istream; // creates an Input Stream and named it "istream"
OutputStream ostream; // creates an Output Stream and named it "ostream"
File inputFile = new File("Data.abc"); //passes file as argument
int c;
final int EOF=-1;
ostream = System.out;
try
{
istream = new FileInputStream(inputFile);
try
{
while((c=istream.read()) !=EOF)
ostream.write(c);
}
catch(IOException e)
{
System.out.println("Error: " + e.getMessage());
}
finally
{
try
{
istream.close();
ostream.close();
}
catch(IOException e)
{
System.out.println("File did not close");
}
}
}
catch(FileNotFoundException e)
{
System.exit(1);
}
}
}

using PrintWriter to write strings to log file

I have a java application that needs to write a lot of data into individual lines in a text file. I wrote the code below to do this, but for some reason, it is not writing anything to the text file. It does create the text file, but the text file remains empty after the program is done running. Can anyone show me how to fix the code below so that it actually fills the output file with as many lines of output as it is called upon to do?
public class MyMainClass{
PrintWriter output;
MyMainClass(){
try {output = new PrintWriter("somefile.txt");}
catch (FileNotFoundException e1) {e1.printStackTrace();}
anotherMethod();
}
void anotherMethod(){
output.println("print some variables");
MyOtherClass other = new MyOtherClass();
other.someMethod(this);
}
}
public class MyOtherClass(){
void someMethod(MyMainClass mmc){
mmc.output.println("print some other variables")
}
}
How you are going about doing this seems very strange to me. Why don't you write one method that takes in a string and then writes it to your file? Something like this should work fine
public static void writeToLog(String inString)
{
File f = new File("yourFile.txt");
boolean existsFlag = f.exists();
if(!existsFlag)
{
try {
f.createNewFile();
} catch (IOException e) {
System.out.println("could not create new log file");
e.printStackTrace();
}
}
FileWriter fstream;
try {
fstream = new FileWriter(f, true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(inString+"\n");
out.newLine();
out.close();
} catch (IOException e) {
System.out.println("could not write to the file");
e.printStackTrace();
}
return;
}
Use the other constructor:
output = new PrintWriter(new FileWriter("somefile.txt"), true);
According to JavaDoc:
public PrintWriter(Writer out, boolean autoFlush)
Creates a new PrintWriter.
Parameters:
out - A character-output stream
autoFlush - A boolean; if true, the println, printf, or format methods will flush the output buffer
Use other constructor new PrintWriter(new PrintWriter("fileName"), true) for auto-flushing data or
Use flush() and close() when you're done writing

list all subfolders in a directory and written on to a text file

I need to list all subfolders in a directory and written on to text file.But when i coded only the last subfolder is only written on to the file.Please help.I am a beginner to Java.
public class Main {
// private Object bufferedWriter;
/**
* Prints some data to a file using a BufferedWriter
*/
public void writeToFile(String filename) {
try
{
BufferedWriter bufferedWriter = null;
bufferedWriter = new BufferedWriter(new FileWriter(filename));
int i=1;
File f=new File("D:/Moviezzz");
File[] fi=f.listFiles();
for(File fil:fi)
{
if(fil.isHidden())
{
System.out.print("");
}
else if(fil.isDirectory()||fil.isFile())
{
int s=i++;
String files = fil.getName();
//Start writing to the output stream
bufferedWriter.write(s+" "+fil);
bufferedWriter.newLine();
// bufferedWriter.write(s+" "+files);
}
}
//Construct the BufferedWriter object
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}catch (IOException ex) {
ex.printStackTrace();}
}
public static void main(String[] args) {
new Main().writeToFile("d://my.txt");
}
}
Uptil you call flush() method of BufferWriter class it will not write your data to file.
It is not necessary to flush() every time in a loop. But you can write it after your end of the loop.
Main thing to put that yourObj.flush() is to keep your buffer memory clean. as after call of that flush() method, data will be release from memory and written to your file.
Close the BufferedReader after the loop.
for(File fil:fi)
{
...
}
bufferedReader.close();
Also, I suggest these changes in your code to make it more readable and efficient:
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filename));
...
if(!fil.isHidden() && (fil.isDirectory() || fil.isFile()))
{
...
}
You can create the BufferedReaderdirectly. Then, you are getting the file name, but not doing anything with it, so just remove the get. And last, you don't have to have put System.out.print(""); in an if to check if the file is hidden. You can use an empty statement or even no code, or use the ! operator to invert.
if(fil.isHidden())
{
; // Do nothing
}
else
{
// Do something
}
if(fil.isHidden()); // Do nothing
else
{
// Do something
}
if(!fil.isHidden)
{
// Do something
}

How do I write the exception from printStackTrace() into a text file in Java?

I need to capture the exception in a text file in Java. For example:
try {
File f = new File("");
}
catch(FileNotFoundException f) {
f.printStackTrace(); // instead of printing into console it should write into a text file
writePrintStackTrace(f.getMessage()); // this is my own method where I store f.getMessage() into a text file.
}
Using getMessage() works, but it only shows the error message. I want all the information in the printStackTrace() including line numbers.
It accepts a PrintStream as a parameter; see the documentation.
File file = new File("test.log");
PrintStream ps = new PrintStream(file);
try {
// something
} catch (Exception ex) {
ex.printStackTrace(ps);
}
ps.close();
See also Difference between printStackTrace() and toString()
Try to expand on this simple example:
catch (Exception e) {
PrintWriter pw = new PrintWriter(new File("file.txt"));
e.printStackTrace(pw);
pw.close();
}
As you can see, printStackTrace() has overloads.
Do set the err/out stream using System class.
PrintStream newErr;
PrintStream newOut;
// assign FileOutputStream to these two objects. And then it will be written on your files.
System.setErr(newErr);
System.setOut(newOut);
There is an API in Throwable interface getStackTrace() which is used internally for printing in console by printStackTrace()
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Throwable.html#getStackTrace()
Try this API to get StackTraceElement and print those elements sequentially.
Hope below example helps you-
package com.kodehelp.javaio;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class PrintStackTraceToFile {
public static void main(String[] args) {
PrintStream ps= null;
try {
ps = new PrintStream(new File("/sample.log"));
throw new FileNotFoundException("Sample Exception");
} catch (FileNotFoundException e) {
e.printStackTrace(ps);
}
}
}
For more detail, refer to this link here

Do I have to close FileOutputStream which is wrapped by PrintStream?

I'm using FileOutputStream with PrintStream like this:
class PrintStreamDemo {
public static void main(String args[]) {
FileOutputStream out;
PrintStream ps; // declare a print stream object
try {
// Create a new file output stream
out = new FileOutputStream("myfile.txt");
// Connect print stream to the output stream
ps = new PrintStream(out);
ps.println ("This data is written to a file:");
System.err.println ("Write successfully");
ps.close();
}
catch (Exception e) {
System.err.println ("Error in writing to file");
}
}
}
I'm closing only the PrintStream. Do I need to also close the FileOutputStream (out.close();)?
No, you only need to close the outermost stream. It will delegate all the way to the wrapped streams.
However, your code contains one conceptual failure, the close should happen in finally, otherwise it's never closed when the code throws an exception between opening and closing.
E.g.
public static void main(String args[]) throws IOException {
PrintStream ps = null;
try {
ps = new PrintStream(new FileOutputStream("myfile.txt"));
ps.println("This data is written to a file:");
System.out.println("Write successfully");
} catch (IOException e) {
System.err.println("Error in writing to file");
throw e;
} finally {
if (ps != null) ps.close();
}
}
(note that I changed the code to throw the exception so that you understand the reason of the problem, the exception namely contains detailed information about the cause of the problem)
Or, when you're already on Java 7, then you can also make use of ARM (Automatic Resource Management; also known as try-with-resources) so that you don't need to close anything yourself:
public static void main(String args[]) throws IOException {
try (PrintStream ps = new PrintStream(new FileOutputStream("myfile.txt"))) {
ps.println("This data is written to a file:");
System.out.println("Write successfully");
} catch (IOException e) {
System.err.println("Error in writing to file");
throw e;
}
}
No , here is implementation of PrintStream's close() method:
public void close() {
synchronized (this) {
if (! closing) {
closing = true;
try {
textOut.close();
out.close();
}
catch (IOException x) {
trouble = true;
}
textOut = null;
charOut = null;
out = null;
}
}
You can see out.close(); which closes output stream.
No you dont need to. PrintStream.close method automatically closes the underlining output stream.
Check the API.
http://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html#close%28%29
No, according to the javadoc, the close method will close the underlying stream for you.
No. It is not require to close other components. when you close stream it automatically close other related component.

Categories