Java read a file line by line – How Many Ways?

Processing a text file line by line is a common thing programmers do. There are many related classes in the Java I/O package and this may get confusing. This post shows 4 different ways of reading a file line by line in Java.

1. FileInputStream and BufferedReader

private static void readFile1(File fin) throws IOException {
	FileInputStream fis = new FileInputStream(fin);
	//Construct BufferedReader from InputStreamReader
	BufferedReader br = new BufferedReader(new InputStreamReader(fis));
	String line = null;
	while ((line = br.readLine()) != null) {

2. FileReader and BufferedReader

private static void readFile2(File fin) throws IOException {
	// Construct BufferedReader from FileReader
	BufferedReader br = new BufferedReader(new FileReader(fin));
	String line = null;
	while ((line = br.readLine()) != null) {

Use the following code:

//use . to get current directory
File dir = new File(".");
File fin = new File(dir.getCanonicalPath() + File.separator + "in.txt");

Both works for reading a text file line by line.

The difference between the two methods is how to construct a BufferedReader object. Method 1 uses InputStreamReader and Method 2 uses FileReader. What's the difference between the two classes? An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset. InputStreamReader can handle other input streams than files, such as network connections, classpath resources, ZIP files, etc.

FileReader is a convenience class for reading character files. The constructors of this class assume that the default character encoding and the default byte-buffer size are appropriate. FileReader does not allow you to specify an encoding other than the platform default encoding. Therefore, it is not a good idea to use it if the program will run on systems with different platform encoding.

Comparing Method 1 & 2, InputStreamReader is a safer choice than FileReader.

3. Files.newBufferedReader()

You can also use the following method which is available since Java 1.7. Essentially, it is the same with Method 1.

Charset charset = Charset.forName("US-ASCII");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
    String line = null;
    while ((line = reader.readLine()) != null) {
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);

The newBufferedReader() method does the following:

public static BufferedReader newBufferedReader(Path path, Charset cs){
 CharsetDecoder decoder = cs.newDecoder();
 Reader reader = new InputStreamReader(newInputStream(path), decoder);
 return new BufferedReader(reader);

4. Lambda in Java 8

From Java 8, we can use a single line to read a file line by line.

 Files.lines(new File("test.txt").toPath()).map(s -> s.trim())
                            .filter(s -> s.startsWith("abc")

Reading the class hierarchy diagram is also very helpful for understanding those inputstream and reader related concept:

Category >> I/O  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
String foo = "bar";
  • gg

    In the fourth example there is a small mistake – missing bracket. Correct:
    .filter(s -> s.startsWith(“abc”))

  • Rahul

    Don’t i need fis.close() before br.close()??

  • Wittahera

    Scanner and Printwriter are more convenient IMO. Both Byte Stream and Character Stream are lower level implementations.

  • ahmed

    may be it is too late feedback but when I tried them BufferedReader method close() also is throwable exception