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.
Related
So I have a working ObjectOutputStream in a method that I start by calling the method in main. I need to then read the file it created and print out all 5 objects in it. Right now I'm only printing out the first object.
public static AccountSerializable serializReadObject() throws ClassNotFoundException, IOException {
AccountSerializable read = null;
try { // Create an input stream for file accounts.ser
ObjectInputStream input = new ObjectInputStream(new FileInputStream("accounts.ser"));
read = (AccountSerializable) input.readObject();
input.close();
} catch (IOException i) {
throw i;
}catch(ClassNotFoundException c){
throw c;
}
return read;
}
public static void main(String[] args) {
try {
System.out.println(serializReadObject());
} catch (ClassNotFoundException | IOException e) {
System.out.println("Class not found");
e.printStackTrace();
}
}
I've tried to throw
boolean eof = false;
while(!eof){
try{
//read data
}catch(EOFException e){
eof = true;
}
}
in serializReadObject To loop it and I've also tried to instead catch it in main but I keep getting an error stating "Unreachable catch block for EOFException it is already handled by the catch block"
I then tried to take away the IOException and just put EOFEception but alas it keeps forcing me to surround my read with IOException. Is there another way to loop this with EOF?
You're only getting the first object because your opening and closing the stream on each call. There are many ways to achieve what you want. One way is to use a List<AccountSerializable>:
public static List<AccountSerializable> serializeReadObjects() throws IOException, ClassNotFoundException {
// create an input stream for file accounts.ser
// this line will throw an IOException if something goes wrong
// we don't need to catch it in this method though
ObjectInputStream input = new ObjectInputStream(new FileInputStream("accounts.ser"));
// create list to hold read in accounts
List<AccountSerializable> accounts = new ArrayList<>();
// keep reading until EOFException is thrown
boolean keepReading = true;
while(keepReading) {
try {
// read in serialized account
AccountSerializable read = (AccountSerializable) input.readObject();
// add read in serialized account to the list
accounts.add(read);
} catch(EOFException eofe) {
// we are at the end of file, so stop reading
keepReading = false;
input.close();
} catch(IOException ioe) {
// input stream error other than EOF, not sure what to do
input.close();
throw ioe;
} catch(ClassNotFoundException cnfe) {
// not sure what to do in this case, so close input
input.close();
throw cnfe;
}
}
return accounts;
}
public static void main(String[] args) {
List<AccountSerializable> accounts = null;
try {
// get list of read in accounts
accounts = serializeReadObjects();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
// iterate over list of read in accounts and output them to stdout
for(AccountSerializable account : accounts) {
System.out.println(account);
}
}
I'm trying to create a new PrintWriter object within a try with resources block as below, but it's giving me an error saying outFile cannot be resolved to a type:
public class DataSummary {
PrintWriter outFile;
public DataSummary(String filePath) {
// Create new file to print report
try (outFile = new PrintWriter(filePath)) {
} catch (FileNotFoundException e) {
System.out.println("File not found");
e.printStackTrace();
}
}
EDIT:
A reason why I didn't want to declare the PrintWriter object within the try block is because I want to be able to reference the outFile object in other methods of my class.
It seems like I can't do it with try with resources, so I created it within a normal try/catch/finally block.
The text file is being created. However, when I try to write to file in another method, nothing seems to be printing in the text file, test.txt.
Why is this??
public class TestWrite {
PrintWriter outFile;
public TestWrite(String filePath) {
// Create new file to print report
try {
outFile = new PrintWriter(filePath);
} catch (FileNotFoundException e) {
System.out.println("File not found");
e.printStackTrace();
} finally {
outFile.close();
}
}
public void generateReport() {
outFile.print("Hello world");
outFile.close();
}
}
Instead of trying to do everything in a constructor, I will demonstrate the preferred way to use a try-with-resources and invoke another method. Namely, pass the closeable resource to the other method. But I strongly recommend you make the opener of such resources responsible for closing them. Like,
public void writeToFile(String filePath) {
try (PrintWriter outFile = new PrintWriter(filePath)) {
generateReport(outFile);
} catch (FileNotFoundException e) {
System.out.println("File not found");
e.printStackTrace();
}
}
private void generateReport(PrintWriter outFile) {
outFile.print("Hello world");
}
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.
public class deleteFile {
public static void main(String args[]){
StringBuffer fileNameStr = new StringBuffer();
fileNameStr.append("c:/");
fileNameStr.append("Test");
File file = new File(fileNameStr.toString());
String systemDateTime = null;
try {
systemDateTime = con.getSystemDateTime();
} catch (SQLException e) {
file.delete();
}
}
}
According to this code, when I get SQLException, it can't delete file. Why?
There is nothing special about deleting a file in a catch block.
If your code (above) is not deleting the file, then it could be a number of things:
You may have the file pathname incorrect.
The file may not exist in the first place.
Your application may not have permission to delete the file, due to normal file / directory permission issues, "mandatory access control" restrictions (e.g. SELinux) or Java sandbox restrictions.
The file may be undeletable because it is "in use" ... on Windows.
That particular exception may not be being thrown.
Your catch block with SqlException never catching.
Use finally{} block in order to delete file or free resource.
Actually my full source code is,
public class deleteFile {
public static void main(String args[]){
-------------------------
StringBuffer fileNameStr = new StringBuffer();
fileNameStr.append(.....);
fileNameStr.append(.....);
File file = new File(fileNameStr.toString());
PrintWriter printWriter = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file),
"windows-31j")));
String systemDateTime = null;
try {
systemDateTime = con.getSystemDateTime();
} catch (SQLException e) {
file.delete();
}
}
Finally I found the solution that is need to close printWriter before deletion file. Thank you for your advice.
try {
systemDateTime = con.getSystemDateTime();
} catch (SQLException e) {
printWriter.flush();
printWriter.close();
file.delete();}
}
I have a valet class method that should write an hourly wage to a file:
public void hourlyOverall() throws FileNotFoundException
{
PrintWriter out = new PrintWriter("wage info");
new FileOutputStream("wage info", true);
hourlyOverall = tips / hours + hourlyWage;
out.println(hourlyOverall);
}
However, when I run valet.hourlyOverall() in my main method, the file "wage info" is created but nothing is written to it. What am I doing wrong?
First of all use try-catch for Exception handling and then in the finally block close the OutputStream
out.flush();
Somthing like this
try {
PrintWriter out = new PrintWriter("wage info");
hourlyOverall=tips/hours+hourlyWage;
out.println(hourlyOverall);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally {
out.flush();
}
I think this is another way to solve your problem, but using another classes
public class valet {
public static void main(String []args)throws IOException
{
try
{
hourlyOverall()
}
catch(IOException ex)
{
System.out.println(ex+"\n");
}
}
public void hourlyOverall() throws IOException
{
FileWriter out = new FileWriter("wage info");
hourlyOverall=tips/hours+hourlyWage;
out.write(hourlyOverall+"\r\n");
out.close();
}
}
You probably shouldn't declare an anonymous FileOutputStream and you should probably close your PrintWriter,
PrintWriter out=new PrintWriter("wage info");
// new FileOutputStream("wage info",true);
hourlyOverall=tips/hours+hourlyWage;
out.println(hourlyOverall);
out.close(); // <-- like that
Do something like this (if java7 or above) :
public void hourlyOverall()
{
try (PrintWriter out=new PrintWriter("wage info")){
//new FileOutputStream("wage info",true);
hourlyOverall=tips/hours+hourlyWage;
out.println(hourlyOverall);
}catch (FileNotFoundException e) {
e.printStackTrace();
}
}
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html