Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Standard idiom for reading text files

 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not very experienced with I/O, and I am interested in knowing what the standard idiom for reading text files is. I am writing a class that reads an entire book (the Bible) from a plain text flat file, and returns the book as a String. Currently my code looks like this.

Specifically, I want to know if it is bad form to have all the reading logic in the constructor.

Also, when reading about writing code for testability, it mentioned that instead of passing a path as a parameter, a Reader should be passed to increase flexibility for testing. But alas, I can no longer find this article and don't really remember the point that was being made.

Garrett
[ April 24, 2006: Message edited by: Garrett Rowe ]
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is the way I would do it, if I were not going to exploit the parsing power of scanner:

 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This would give me pause in a constructor, but maybe it really is the right time to do this.

The Reader idea is neat. If you defined your method like this:

then normal production code would call it like

but a test could call it like:

That lets you test the reader without having any files around, which is much faster and more reliable than writing a new file just for test purposes. It would also let you hook your Thing up to a socket or any other kind of Reader in the future. Neat, huh?
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
BTW: Be very careful hooking your Thing up to a socket. If you happen to be standing in a puddle of water ... well, it's bad.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replys guys. The idea of passing a Reader is much more appealing now that I see the flexibility of it. The problem with reading the text one line at a time is that I really wanted to read the enitre text into memory so that I could quickly do searches for certain words, phrases, chapters, verses etc.. That was the reason I wrapped the reader in a Scanner, so that I could read the entire file in a fairly compact manner. Is there any way to accomplish this using a BufferedReader. Or should I be looking at a different solution altogether?
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
BTW: Be very careful hooking your Thing up to a socket. If you happen to be standing in a puddle of water ... well, it's bad.


Thank you for finally giving me a legitimate reason to use !
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The loop reading one line at a time is very common, but admittedly we're usually looking at each line as we go. See if you can't build a Scanner on a BufferedReader which is a Readable.
 
Vlado Zajac
Ranch Hand
Posts: 245
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would suggest using a StringWriter, InputStreamReader (to convert the InputStream from .getResourceAsStream() to Reader) and a char[] as buffer.

Then use a loop to read buffer from the Reader, write the buffer to the StringWriter and repeat until end of input.

StringWriter's toString() method will then return the file contents as String.

You may need to set character encoding for the InputStreamReader.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the comments and suggestions everyone. I tested passing a Reader to the constructor, wrapping the Reader ina BufferedReader, and then reading line by line using the standard while() loop, at each line writing the contents to a StringWriter. The problem with that is that since the readLine() method doesn't read the line terminators, the formating was lost.

So then I tried wrapping the StringWriter in a PrintWriter and using the println() method of PrintWriter to write line by line. That worked perfectly.
However it had the disadvantage of being more complex than simply using a Scanner. So in the end, unless I am presented with some compelling reason not to use a Scanner in this situation, it seems like the most straightforward solution. Here is the code as it stands now.

Again thanks for all the suggestions and I certainly welcome any more.
[ April 26, 2006: Message edited by: Garrett Rowe ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic