Reading text files from hard disk is quite common task in software development practice. Usually we are interested in processing it line by line. In this article I would like to present few popular ways how to do it easily using Java IO.
Reading whole file into memory
Reading a text file can be as simple as calling single Files.readAllLines() method:
Path path = Paths.get(fileName); List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8); for (String line : lines) { System.out.println(line); }
This method reads the whole file with given path and stores all its lines into an array of String. The rest of the code just prepares the path and prints the read lines.
While it may seem like a perfect method, it has one significant drawback. If the file being read is large, the created array will be very long. As a result memory usage of the application and the whole JVM will grow significantly which can reduce the performance of the application or in worse case kill the application with infamous OutOfMemoryError.
Therefore, usage of this method must be done with care and only in cases where the input file is small.
Reading file using BufferedReader
If you are going to read large file, you can resort to using BufferedReader class:
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) { while (true) { String line = reader.readLine(); if (line == null) { break; } System.out.println(line); } }
First, we are creating a FileReader instance to access the given file. Because FileReader provides only very basic set of operations, we are wrapping it inside BufferedReader which has more convenient and richer interface. Finally, we call BufferedReader.readLine() method to read each line separately as long as this method returns non-null. Try-with-resources block ensures that the file is always closed at the end.
If using Java 7 or later, creation of BufferedReader can be simplified using Files class:
Path path = Paths.get(fileName); try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { while (true) { String line = reader.readLine(); if (line == null) { break; } System.out.println(line); } }
Reading file using Java 8 streams
Java 8 brought new streams feature into the standard library. The Files class was also extended with new Files.lines() method which opens the file with given path and creates a stream with all the lines of the file. Then the stream of lines can be processed as any other stream of String including filter, map/transform and aggregate operations. In our case we print the lines only:
Path path = Paths.get(fileName); try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) { lines.forEachOrdered(System.out::println); }
This method has the advantage over the first presented method because the file is not read into memory at once but lazily.
Conclusion
Usage of BufferedReader is the most popular and versatile method to read a text file. If you are sure that the file is small, you can use Files.readAllLines() method to simplify the source code. The last method utilizing the streams API is very promising but requires Java 8 runtime environment which is still not an option in many cases (e.g. legacy systems, compatibility, long-running projects).
As always the source code of the example is available at GitHub.