Java IO, are these resources automatically closed? - java

In this code I read a text file, when BufferedReader is closed by "try-resource" block so the InputStreamReader does, then can I guarantee all the resources are closed like this?
try(final BufferedReader br = new BufferedReader(new InputStreamReader(new
FileInputStream(file), charset))) {
String line = null;
while((line = br.readLine()) != null) {
builder.append(line);
}
}
In this other example, I write a text file, as is written, are all the resources closed in the end? Is it mandatory to call flush()?
try(final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new
FileOutputStream(file), charset))) {
bw.write(text);
bw.flush();
}

Yes, the outermost streams call their inner streams' close() methods, so you only need to call the outermost stream.
You don't need to call flush(), the streams will flush when necessary and before being closed. Remove that and the code will look perfect.

Related

Java program is not writing all the records to the output file using the BufferedWriter

This below code is not able to write more than 29499 lines in the output file. More over the last line was printed only half. I have verified there is no issue with the program as the program is print all the 25000 lines in console.
FileReader fr = new FileReader(System.getProperty("user.dir") + "/json/Sample.json");
FileWriter fw = new FileWriter(System.getProperty("user.dir") + "/json/output.json");
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
String line=br.readLine();
if (line == null)
{
br.close();
fr.close();
bw.flush();
bw.close();
fw.close();
}
while (line!=null) {
Gson gson = new Gson();
bw.write(record+"\n");
line=br.readLine();
}
You only close and flush your readers & writers if the first line is null. You presumably instead want to do this after your loop completes, which will ensure that (exceptions aside) they'll always close.
Even better, use the try with resources statement to avoid having to close / flush them manually at all - this will also handle the case where an exception it thrown.

File Reading in Java, with same file readers

I have two files to be read using same variables for the task with the following code:
try {
FileInputStream fis = new FileInputStream(filename1);
InputStreamReader isr = new InputStreamReader(fis, "UTF8");
BufferedReader br = new BufferedReader(isr);
String line="";
while((line=br.readLine())!=null){
System.out.println(line);
}
// Do i need to add these 3 statements ...
//br.close();
//isr.close();
//fis.close();
//Without the above 3 statements also the code works fine ...
fis = new FileInputStream(filename2);
isr = new InputStreamReader(fis, "UTF8");
br = new BufferedReader(isr);
line="";
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
isr.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
The filereading in java doesn't bother about closing the opened stream and releasing any system resources associated with it for the first file filename1?
No exceptions thrown.
So you have a resource leak which won't cause a problem for you unless you;
attempt to delete the file on Windows (as the file is still open)
do this many times in which case you might run out of file handles.
The code works, but it is not a good practice.
Java will automatically close the first file when the garbage collector decides to run and to deallocate your first FileInputStream object. This might happen at any time after you lose the last reference to the object, but might even not happen at all, depending on your memory conditions.
If you are using Java 7, you can use the try with resources construct, which will call close for you:
try (FileInputStream fis = new FileInputStream(filename1);
InputStreamReader isr = new InputStreamReader(fis, "UTF8");
BufferedReader br = new BufferedReader(isr)) {
// Code...
}
Once you created new instance for the StreamReader, Automatically call the garbage collection for the previously opened stream.

BufferedWriter is not writing to ByteArrayOutputStream

I want to convert an input stream to byte array. I know I can use IOUtils from commons-io. But I am practicing some basics in java io. I read an xml file using BufferedReader and tried writing it to a ByteArrayOutputStream using BufferedWriter. But its not working.
When I write directly to the ByteArrayOutputStream its working. Whats wrong in my code?
try (InputStream inputStream = getClass().getResourceAsStream(
"/productInventory.xml");
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(arrayOutputStream));
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));) {
String line = "";
while ((line = bufferedReader.readLine()) != null) {
bufferedWriter.write(line);
}
System.out.println(arrayOutputStream.size());
} catch (IOException e) {
e.printStackTrace();
}
When I include below line in the loop its working
arrayOutputStream.write(line.getBytes(), 0, line.getBytes().length);
What is wrong while using BufferedWriter?
Nothing's wrong - it's just buffering! :D
The BufferedWriter works by filtering everything you send into it into a buffer - when the buffer is full, or when the writer is closed, or flushed, (It's a Closeable, so you should absolutely close it), it sends along those buffered characters to the underlying writer.
If you want to see the underlying writer update you have to either:
1) Fill up the buffer (default size is 8k in Java)
2) Call .flush()
3) Call .close()
4) As mentioned in comments, you can do a try-with-resources to make the close implicit:
try (BufferedWriter writer = new BufferedWriter(underlyingWriter)) {
// doStuff
}

BufferedReader then write to txt file?

Is it possible to use BufferedReader to read from a text file, and then while buffered reader is reading, at the same time it also storing the lines it read to another txt file using PrintWriter?
If you use Java 7 and want to copy one file directly into another, it is as simple as:
final Path src = Paths.get(...);
final Path dst = Paths.get(...);
Files.copy(src, dst);
If you want to read line by line and write again, grab src and dst the same way as above, then do:
final BufferedReader reader;
final BufferedWriter writer;
String line;
try (
reader = Files.newBufferedReader(src, StandardCharsets.UTF_8);
writer = Files.newBufferedWriter(dst, StandardCharsets.UTF_8);
) {
while ((line = reader.readLine()) != null) {
doSomethingWith(line);
writer.write(line);
// must do this: .readLine() will have stripped line endings
writer.newLine();
}
}
To directly answer your question:
you can, and you can also use BufferedWriter to do so.
BufferedReader br = new BufferedReader(new FileReader(new File("Filepath")));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("Filepath")));
String l;
while((l=br.readLine())!=null){
... do stuff ...
bw.write("what you did");
}
bw.close();
If you just need to copy without inspecting the data, then it's a one liner:
IOUtils.copy(reader, printWriter);
Yes. Open the BufferedReader, and then create a PrintWriter. You can read from the stream as you write to the writer.

Closing nested Reader

When reading from a text file, one typically creates a FileReader and then nests that in a BufferedReader. Which of the two readers should I close when I'm done reading? Does it matter?
FileReader fr = null;
BufferedReader br = null;
try
{
fr = new FileReader(fileName);
br = new BufferedReader(fr);
// ...
}
finally
{
// should I close fr or br here?
}
I'm a little paranoid when it comes to exception-safety. What happens when the BufferedReader constructor throws an exception? Does it close the nested reader? Or is it guaranteed not to throw?
Generally, close() on the outermost stream wrapper will call close() on the wrapped streams. However, if you think it's likely that a constructor will throw an exception, make liberal use of the Closeable interface.
FileReader fr = new FileReader(fileName);
Closeable res = fr;
try {
BufferedReader br = new BufferedReader(fr);
res = br;
} finally {
res.close();
}
So, even if the JVM ran out of heap space for the buffer and threw an error, you wouldn't leak a file handle.
For Java 7 and above use try-with-resources:
try (FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr)) {
// do work
}
Closing only the BufferedReader is enough, cause it wraps the FileReader. If you look at the source code of BufferedReader you will see that the close method, closes the wrapped stream.
Close the BufferedReader in a finally block.
If you call the BufferedReader's close method, the BufferedReader will call the FileReader's close method. Thus both close method's are called. More precisely the BufferedReader will do nothing BUT calling the FileReader's close method. Thus it does not matter at all. Though I think it is good practice too call the BufferedReader's close method.
Nothing is guaranteed not to throw. Because the buffer is allocated it may throw OutOfMemoryError. I usually separate my code into 2 sections: acquire resources and then use resources. Each section usually has unique cleanup needs
Here is the code to illustrate:
// Acquire resources section.
final FileReader fr = new FileReader( fileName );
BufferedReader br = null;
try
{
br = new BufferedReader(fr);
}
finally
{
if ( br == null )
{
// Note that you are closing the fr here
fr.close( );
}
}
// Use resources section
try
{
// ... use br
}
finally
{
// Now that br is safely constructed, just all its close
br.close( );
}
And I agree with you, there is nothing worth than silently loose a file handler in the long running server application.

Categories