Reading a File in Java -- Beautifully
Thursday, 25. October 2007, 09:16:32
Till today, I used to read an entire text file like this:
String newLine = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append(newLine);
}
return sb.toString();
That's not beautiful. But today I came up with this alternative:
String newLine = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
for (String line = br.readLine(); line != null; line = br.readLine()) {
sb.append(line).append(newLine);
}
return sb.toString();
And I like its beauty. What do you think? Isn't this more beautiful?
It would be more convenient if BufferedReader had a readFile() method though. Also it makes sense to make BufferedReader iterable so we could have:
for (String line : buffReader) { // do something with line }
When you do that often, why not write your own FileReader returning a Iterator<Sting> object. Shouln't be more than 10 lines of code.
Peace
-stephan
--
Stephan Schmidt :: stephan@reposita.org
Reposita Open Source - Monitor your software development
http://www.reposita.org
Blog at http://stephan.reposita.org - No signal. No noise.
By anonymous user, # 25. October 2007, 12:10:37
Try this:
Scanner scanner = new Scanner(file);
scanner.useDelimiter("\\A");
String content = scanner.next();
scanner.close();
return content;
By anonymous user, # 25. October 2007, 14:31:33
@Anon: Excellent suggestion. Didn't know about that class in the 1.5 JDK.
Thanks
-stephan
By anonymous user, # 25. October 2007, 15:04:00
That makes sense, but every now and then that I have to experiment with something or write a tiny small project (say, less than 1000 lines), if I need to read form a file, I usually do that manually. It is not that cumbersome after all. I don't know why I hesitate to create my common utilities JAR file. Oh, btw, Commons IO has this neat readFileToString() method but again, I refuse to use extra libs for my small projects. Maybe I prefer this approach, because in general, I like to have a minimal dependency on external JAR files. Maybe I have to rethink about this attitude of mine thought.
One cool thing to do is to write a code snippet template in IDEA or Eclipse , say named rdfl (for readfile), and then by expanding it, it would insert the above chunk of code (something a little bit more complex) at caret position.
@Anonymous,
That was even more beautiful, but I assume more resource hungry, which is of course not important at all for a small experimental project.
By behrangsa, # 25. October 2007, 17:23:52
How is this "beautiful"? It's the intended use of a for loop.
By anonymous user, # 25. October 2007, 20:23:48
Almost everywhere, I have seen people using the while-loop approach for reading files. This leaves a line variable in a broader scope than it is necessary to be. Of course, this peice of code is usually wrapped inside a method. But again, IMO, the for loop is more beautiful than the while loop. Trivial but worthy nonetheless.
By behrangsa, # 25. October 2007, 21:48:43
This is a bit longer than 10 lines but the end result is elegant, I might use this in future.
public class LineReader {
public static Iterable<String> readText(final String filename) {
return new Iterable<String>() {
public Iterator<String> iterator() {
final BufferedReader br;
try {
br = new BufferedReader(new FileReader(filename));
} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
}
return new Iterator<String>() {
String line = null;
public boolean hasNext() {
try {
line = br.readLine();
} catch (IOException e) {
line = null;
close();
throw new IllegalStateException(e);
}
if (line == null)
close();
return line != null;
}
public String next() {
if (line == null) throw new NoSuchElementException();
return line;
}
public void remove() {
throw new UnsupportedOperationException();
}
protected void finalize() throws Throwable {
super.finalize();
close();
}
private void close() {
try {
br.close();
} catch (IOException ignored) {
// ignored or logged on debug.
}
}
};
}
};
}
public static void main(String ... args) {
for(String line: readText(args[0])) {
System.out.println(line);
}
}
}
By anonymous user, # 27. October 2007, 21:39:50
The formattings not the best.
<pre>
public class LineReader {
public static Iterable<String> readText(final String filename) {
return new Iterable<String>() {
public Iterator<String> iterator() {
final BufferedReader br;
try {
br = new BufferedReader(new FileReader(filename));
} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
}
return new Iterator<String>() {
String line = null;
public boolean hasNext() {
try {
line = br.readLine();
} catch (IOException e) {
line = null;
close();
throw new IllegalStateException(e);
}
if (line == null)
close();
return line != null;
}
public String next() {
if (line == null) throw new NoSuchElementException();
return line;
}
public void remove() {
throw new UnsupportedOperationException();
}
protected void finalize() throws Throwable {
super.finalize();
close();
}
private void close() {
try {
br.close();
} catch (IOException ignored) {
// ignored or logged on debug.
}
}
};
}
};
}
public static void main(String ... args) {
for(String line: readText(args[0])) {
System.out.println(line);
}
}
}
</pre>
By anonymous user, # 27. October 2007, 21:40:51
Looks like Opera is facing some issues regarding the formatting of comments for the time being: http://my.opera.com/community/forums/topic.dml?id=210362 but your LineReader was interesting.
By behrangsa, # 27. October 2007, 22:57:48
Hello!
I have a problem. I have to write a method in order to return a the next line from a file. When I call de method always returns the first line.What can I do?
public String nextEntry()throws IOException
{
BufferedReader br= new BufferedReader(new FileReader("file.txt"));
return br.readLine();
}
By anonymous user, # 1. December 2007, 18:30:00
Anonymous, you're reinitialising your BufferedReader everytime nextEntry() is called, you need to declare it outside of the method. That way its state will persist.
By anonymous user, # 4. January 2008, 00:42:51
you guys are total fags
By anonymous user, # 28. January 2008, 05:25:51
if you like the simplicity of the for-loop, then why do you have the call to readLine() twice. You should do:
for( String line; (line = reader.readLine()) != null; ) {
}
By anonymous user, # 19. February 2008, 22:32:23