What do I need to close when using PrintWriter in Java [duplicate] - java

This question already has answers here:
Correct way to close nested streams and writers in Java [duplicate]
(10 answers)
Closed 6 years ago.
When using a PrintWriter like this :
PrintWriter fileOut = new PrintWriter(new BufferedWriter(new FileWriter(csvFileIn)));
What do I need to close in the finally block ? The PrintWriter, the BufferedWriter and the FileWriter ?
Do I need to try catch the close statement in the finally block ?
[EDIT]
I need to use java 6, so I can't use the try-with-resources statement.

You can use a try-with-resources block
try (PrintWriter fileOut = new PrintWriter(new BufferedWriter(new FileWriter(csvFileIn)))) {
//WHATEVER you need to do
}
Since PrintWriter implements AutoCloseable it will close by itself once the try block is complete (even if an exception is raised)
Check more info about this here

You should use -
fileOut.close();
As you do not have any variable name assigned to BufferedWriter or FileWriter also the fileOut is made from them when you close fileOut it will in turn close both the streams.

Strictly speaking, you should close all three streams. And I would even add a fourth layer, since you probably don’t want to write out the CSV file using the default system encoding, but a customer-specified one. So this is it:
try (FileOutputStream fos = new FileOutputStream(csvFileIn);
FileWriter fwr = new FileWriter(fos, StandardEncodings.UTF_8);
BufferedWriter bwr = new BufferedWriter(fwr);
PrintWriter pwr = new PrintWriter(bwr)) {
pwr.println("Field1;Field2;Field3");
pwr.println("Data1;Data2;Data3");
}
In practice, usually only the outermost stream is closed, since it (usually) forwards the close() call to its wrapped stream, and getting an OutOfMemoryError between opening the file and reaching the try block is very unlikely. Then, it looks like this:
try (PrintWriter pwr = new PrintWriter(new BufferedWriter(new FileWriter(new FileOutputStream(csvFileIn), StandardEncodings.UTF_8)))) {
pwr.println("Field1;Field2;Field3");
pwr.println("Data1;Data2;Data3");
}

Related

Close a stream without assigning it to a variable [Java]

I'm reading a large file using the nio Files.lines method, and writing it to another file.
BufferedWriter writer = Files.newBufferedWriter(Path.of(outFile);
Files.lines(Path.of(inputFile))
.forEach(line -> {
try {
writer.write(line);
writer.newLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
writer.flush();
writer.close();
I want to close the writer and the stream (Files.lines) in a finally block.
I'm aware I'll have to surround this snippet in a try-catch-finally block, but how do I close the stream without assigning it to a variable?
Instead of doing lots of manual work, just use the following snippet (as you've been advised already in the comments):
Files.copy(Path.of(inputFile), Path.of(outFile)));
If you still want to do that manually for some reason, use try-with-resources. You will still assign the BufferedWriter to a variable, but there'll be no need to close it explicitly. Java will do that by itself:
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(outFile));
Stream<String> lines = Files.lines(Path.of(inputFile))) {
// ... do something with your lines & writer here
}

do i need call close() on every new inputstream?

here is the code.
public static void main(String[] args) throws IOException {
FileInputStream fis = null;
fis = new FileInputStream(new File("D:\\za180s.ser"));
// do something
fis = new FileInputStream(new File("D:\\za185s.ser"));
// do something
fis = new FileInputStream(new File("D:\\za186s.ser"));
// do something
fis = new FileInputStream(new File("D:\\za187s.ser"));
// do something
fis.close();
}
the problem is : need i call fis.close() method after every "do something" or i just call fis.close() once after all.
ignore whether the close() position in finally and the code need try catch or not.
thx all.
Yes, you need to call close on each individual InputStream. The problem with your code is that you're reassigning the variable fis each time you create a new stream. In other words: fis no longer points to the old InputStream, so calling close will not close the previous stream.
For more information, check https://stackoverflow.com/a/40523/8819761
What you could also do is use Java 7's try-with-resources syntax, which will auto-close the stream once you exit the try block:
try (InputStream fis = new FileInputSteam(yourFile)) {
// Do something
}
try (InputStream fis = new FileInputSteam(yourFile)) {
// Do something else
}
You have to do close everytime you finish working with InputStream.
In java, if you assign
fis = new FileInputStream(new File("D:\\za180s.ser"));
fis will point to the new object so when you call fis.close() the old streams are not affected. And there is no way to close it.
You need to call close method every time but don't worry now.From Java SE 7 you can use try-with-resources. As per Java-Oracle Doc,
The try-with-resources statement is a try statement that declares one
or more resources. A resource is an object that must be closed after
the program is finished with it. The try-with-resources statement
ensures that each resource is closed at the end of the statement. Any
object that implements java.lang.AutoCloseable, which includes all
objects which implement java.io.Closeable, can be used as a resource.
Please have a look on example.
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).
For more details, Please have a look on Oracle-Java doc for try-with-resources.
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

How should I check if BufferedWriter is already closed?

In android, I am writing a file on clicking a button and on clicking next time, it saves the file and closes the buffered writer. But, I also want to implement functionality to close the buffered writer in onDestroy function. Before that I need to know if Bufferedwriter is already closed. How will I check if Buffered Writer is already closed?
In addition to that, does bufferedWriter.close() function set bufferedWriter to null?
Calling close method on already closed Writer has no impact.
Still, if you want to know if the Writer is closed, you can call writer.flush(), if it throws IOException then it means the Writer is already closed.
For your second question, closing a stream doesn't nullify the reference. You have to explicitly set it to null.
you can check if bufferredWriter not equal to null
if(bufferredWriter!=null)
{
bufferredWriter.close();
}
If you are using java7 or more then you need not to worry about closing the BufferredWriter
JDK 7 onwards you can make you of try with resource
for example
try(BufferredWriter bufferedWriter=new BufferredWriter())
{
//your code
}
catch(Exception e)
{
}
BufferedWriter vf = new BufferedWriter(new FileWriter("file"));
if (vf != null)
{
vf.close();
vf.close(); //won't cause any problem
}
you can close BufferedWriter as many times as you want if it is not null. So no need to check specifically if BufferedWriter is open or not.
Even better if you surround close statement in try/catch in case IOException occurs.
From javadocs
Closes the stream, flushing it first. Once the stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously closed stream has no effect.
And as explained by sidgate, closing a stream won't nullify the reference you have to assign it manually.
bufferedWriter.close() - Closes this writer. The contents of the buffer are flushed, the target writer is closed, and the buffer is released. Only the first invocation of close has any effect.
Refer this
Also, you can check like this
Define below 2 variables as instance variable
BufferedWriter bufferWriter;
boolean isOpen = false;
Then,
try {
if (!isOpen) {
bufferWriter = new BufferedWriter(new FileWriter(file, true));
bufferWriter.write(initialData);
isOpen = true;
}
bufferWriter.write(remainingData);
bufferWriter.flush();
Log.d(TAG, "written to file:" + file.getAbsolutePath());
} catch (IOException e) {
Log.v("IOException", e.toString());
}

Writing to Text File [duplicate]

This question already has answers here:
BufferedWriter not writing everything to its output file
(8 answers)
Closed 8 years ago.
So I'm using this function to write to text file, but the text file always ends up empty after executing. Can anyone see what the error might be? I've been stuck on this for a while.
public static void writeTextFile(String fileName, String s) {
FileWriter output = null;
try {
output = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(output);
writer.write(s);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
// Ignore issues during closing
}
}
}
}
Just change your to include writer.close(); as given below
try {
output = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(output);
writer.write(s);
writer.close();
}
//remaining code
The reason your data not saved in the file because , The Data is saved only if you call writer.flush(); And calling the writer.flush() method is enough to just save data. But you need to close the BufferedWriter() like writer.close(); to avoid resource leak. The close() calls flush() method for you before closing the stream.
After writing your output you should make sure to flush and close the socket, specially because you are using a buffered output.
writer.write(s);
writer.flush();
writer.close();
If you don't do that, the BufferedWriter will wait for additional data, but there does come none and the program execution is stopped suddenly. Using flush here is optional, as when closing it the flush is implicit, but personally I call it everytime I need to be sure that something goes out. Just like when on the toilet ;)
When you use a Buffer to write something, you must close him when you re end
writer.close();
Without closing bufferwriter you cannot see output on text file
try to add this code
writer.close()

BufferedReader to BufferedWriter

How can I obtain a BufferedWriter from a BufferedReader?
I'd like to be able to do something like this:
BufferedReader read = new BufferedReader(new InputStreamReader(...));
BufferedWriter write = new BufferedWriter(read);
You can use the following from Apache commons io:
IOUtils.copy(reader, writer);
site here
JAVA 9 Updates
Since Java 9, Reader provides a method called transferTo with the following signature:
public long transferTo(Writer out) throws IOException
As the documentation states, transferTo will:
Reads all characters from this reader and writes the characters to the given writer in the order that they are read. On return, this reader will be at end of the stream. This method does not close either reader or writer.
This method may block indefinitely reading from the reader, or writing to the writer. The behavior for the case where the reader and/or writer is asynchronously closed , or the thread interrupted during the transfer, is highly reader and writer specific, and therefore not specified.
If an I/O error occurs reading from the reader or writing to the writer, then it may do so after some characters have been read or written. Consequently the reader may not be at end of the stream and one, or both, streams may be in an inconsistent state. It is strongly recommended that both streams be promptly closed if an I/O error occurs.
So in order to write contents of a Java Reader to a Writer, you can write:
reader.transferTo(writer);
If you want to know what happens:
All input from the reader is copied to the inputstream
Something similar too:
private final void copyInputStream( InputStreamReader in, OutputStreamWriter out ) throws IOException
{
char[] buffer=new char[1024];
int len;
while ( ( len=in.read(buffer) ) >= 0 )
{
out.write(buffer, 0, len);
}
}
More on input and output on The Really big Index
BufferedWriter constructor is not overloaded for accept readers right? what Buhb said was correct.
BufferedWriter writer = new BufferedWriter(
new FileWriter("filename_towrite"));
IOUtils.copy(new InputStreamReader(new FileInputStream("filename_toread")), writer);
writer.flush();
writer.close();
You could use Piped Read/Writers (link). This is exactly what they're designed for. Not sure you could retcon them onto an existing buffered reader you got passed tho'. You'd have to construct the buf reader yourself around it deliberately.

Categories