• Post Reply Bookmark Topic Watch Topic
  • New Topic

Best Practice for BufferedReader

 
Lilian Chase
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hello...

In my application, I get a list of files that I need to open for reading.
I iterate the list using a for loop and BufferedReader to open the files for reading.

My question is: Do I need to close the stream at the end of each loop or it's okay since at the start of the loop,
the BufferedReader is reinitialized with the new file as long as I close the stream in the finally block?

I've tried both ways, doesn't throw any Exception or error that I can see. So what would be the best practice?

 
Chris Janicki
Greenhorn
Posts: 23
Mac OS X Netbeans IDE Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, you need to close it each time. Sure, the old BufferedReader objects may eventually get garbage collected (which may automatically close them in some recent version of java, I think?) , but until they are closed, they hold "file descriptors" on your operating system. On Unix at least, each user id only gets to open 1024 (varies per system), then no more files can be opened. If your list.size() > 1024, then the tight for-loop may open all the descriptors before any are reclaimed, and your app will fail with an exception (sometimes with a rather unclear explanatory text).
 
Lilian Chase
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So for the following:



That code line just reassigns the BufferedReader to point to another memory location where the file is at?
So if I do not close the stream, the file descriptor from the previous loop is still there awaiting to be garbage collected?
Is that how it is?
 
Chris Janicki
Greenhorn
Posts: 23
Mac OS X Netbeans IDE Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, that's basically it. Note that the file descriptor is a resource in the operating system, not Java. Calling close() on the BufferedReader releases it. (More precisely, the close() call bubbles all the way up to your FileInputStream, which then tells the O/S to release the descriptor)

In all versions of Java, your orphaned BufferedReader object instances (and the associated hierarchy of I/O classes you instantiated, all the way up to FileInputStream) will eventually be garbage collected. But only the latest versions of Java automatically call close() for you during the garbage collection. I think that feature appears in Java 7. But regardless, the garbage collector only runs every so often. So even if the garbage collector does close things for you, your loop still might quickly use up all the descriptors before garbage collection starts. The best practice is to explicitly call close(). Even if programmers can start getting "lazy" with Java 7, you'll still need to be wary of files opened quickly in loops of unlimited size.

Note that the same goes for opening/closing sockets… the same pool of file descriptors are used for those.
 
Lilian Chase
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Chris for your explanation. You've been a tremendous help
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!