File Reading in Java, with same file readers - java

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.

Related

Java IO, are these resources automatically closed?

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.

Java: Unable to read file using FileReader [duplicate]

I'm trying to read input from a file to be taken into a Java applet to be displayed as a Pac-man level, but I need to use something similar to getLine()... So I searched for something similar, and this is the code I found:
File inFile = new File("textfile.txt");
FileInputStream fstream = new FileInputStream(inFile);//ERROR
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
The line I marked "ERROR" gives me an error that says "Default constructor cannot handle exception type FileNotFoundException thrown by implicit super constructor. Must define an explicit constructor."
I've searched for this error message, but everything I find seems to be unrelated to my situation.
Either declare a explicit constructor at your subclass that throws FileNotFoundException:
public MySubClass() throws FileNotFoundException {
}
Or surround the code in your base class with a try-catch block instead of throwing a FileNotFoundException exception:
public MyBaseClass() {
FileInputStream fstream = null;
try {
File inFile = new File("textfile.txt");
fstream = new FileInputStream(inFile);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// Do something with the stream
} catch (FileNotFoundException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
try {
// If you don't need the stream open after the constructor
// else, remove that block but don't forget to close the
// stream after you are done with it
fstream.close();
} catch (IOException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
Unrelated, but since you are coding a Java applet, remember that you will need to sign it in order to perform IO operations.
You need to surround your code with try and catch as follows:
try {
File inFile = new File("textfile.txt");
FileInputStream fstream = new FileInputStream(inFile);//ERROR
} catch (FileNotFoundException fe){
fe.printStackTrace();
}
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
This is guesswork as we don't have the complete code.
From the Javadoc:
public FileInputStream(File file) throws FileNotFoundException
It means that when you do a new FileInputStream() like you do, it can come back with a FileNotFoundException. This is a checked exception, that you need to either rethrow (i.e. add 'throws FileNotFoundException' in the method where you do the new) or catch (see other try/catch responses).

File created by try instruction?

try(ObjectOutPutStream utfil = new ObjectOutPutStream
(new FileOutputStream("src/eierliste.data")))
Does this instruction create the file for me, or do I have to manually create the file?
Where is src located? Which folder? What does that mean: "src/eierliste.data"
This is a new syntax present since Java 7, it's called try-with-resources. It's a shortcut to ensure that the resource opened within the try is closed automatically when the block ends, what you'd normally do in a finally block. Quoting the tutorial, this:
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
… is equivalent to this:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null)
br.close();
}
Now regarding the code in the question: it's creating a new file only if it didn't exist before (see this answer), and it's opening an ObjectOutPutStream for writing to it.

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
}

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