Introduction

Due to its lack of synchronization, the Scanner class is not thread-safe.Java offers a number of ways to read files. Each of these approaches is suitable for reading various file formats in various circumstances. Others are better at reading shorter files, while some excel at reading larger ones.

The following Java classes will be utilized in this tutorial to read files:

  1. BufferedReader
  2. Files
  3. Scanner

We use a file that is located in the src directory and whose path is src/file.txt throughout the course. Before continuing, save a few lines of text in this file. Note: To adhere to the best coding principles when utilizing these implementations, you must correctly handle the errors.

Java Text File Reading Using BufferedReader

The character input stream is read by the BufferedReader class. To improve reading efficiency, it buffers characters in an 8 KB default size buffer. Using BufferedReader is a wise choice if you wish to read a file line at a time.

When reading large files, BufferedReader performs well.

import java.io.*;

public class FileReaderWithBufferedReader {

    public static void main(String[] a) throws IOException{
        String file = "src/file.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

        String curLine;
        while ((curLine = bufferedReader.readLine()) != null){
            //process the line as required
            System.out.println(curLine);
        }
        bufferedReader.close();
    }
}

When the file's end is reached, the readline() function returns null. Remember to close the file when reading is complete.

Reading UTF-8 File with BufferedReader

Java's BufferedReader is used to read a UTF-8-encoded file. The BufferedReader class may be used to read a UTF-8-encoded file. This time, while constructing a BufferedReader instance, we supply an InputStreamReader object.

import java.io.*;

public class EncodedFileReaderWithBufferedReader {

    public static void main(String[] a) throws IOException {
        String file = "src/fileUtf8.txt";
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));

        String curLine;
        while ((curLine = bufferedReader.readLine()) != null){
            //process the line as you require
            System.out.println(curLine);
        }
    }
}

Using Files Class to Read a File in Java

The Java Files class, which debuted in Java 7's Java NIO, is entirely made up of static methods that work with files. You are able to read a file's whole contents into an array using the Files class. It is a decent option for reading smaller files because of this. Let's examine how the Files class may be used in these two situations.

Dealing with Small Size Files

The Files class's readAllLines() method enables reading the entire file's content and saves each line as a string in an array. Since the Files class accepts the Path object of the file, you can use the Path class to obtain the path to the file.

import java.io.IOException;
import java.nio.file.*;
import java.util.*;

public class SmallFileReaderWithFiles {

    public static void main(String[] a) throws IOException {
        String file = "src/file.txt";
        Path path = Paths.get(file);
        List<String> lines = Files.readAllLines(path);
    }
}

Instead of retrieving the data from the file to a string array, you can use readAllBytes() to retrieve the data to a byte array.

byte[] bytes = Files.readAllBytes(path);

Big Size File Reading with Files Class

The newBufferedReader() method of the Files class can be used to create an instance of the BufferedReader class, which can then be used to read a large file line by line.

import java.io.*;
import java.nio.file.*;

public class LargeFileReaderWithFiles {

    public static void main(String[] a) throws IOException {
        String file = "src/file.txt";
        Path path = Paths.get(file);
        BufferedReader bufferedReader = Files.newBufferedReader(path);

        String curLine;
        while ((curLine = bufferedReader.readLine()) != null){
            System.out.println(curLine);
        }
        bufferedReader.close();
    }
}

Reading Files with Files.lines()

The Files class now has a new method that allows the entire file to be read into a stream of strings in Java 8.

import java.io.IOException;
import java.nio.file.*;
import java.util.stream.Stream;

public class FileReaderWithFilesLines {

    public static void main(String[] a) throws IOException {
        String file = "src/file.txt";
        Path path = Paths.get(file);
        Stream<String> lines = Files.lines(path);

        lines.forEach(s -> System.out.println(s));
        lines.close();
    }
}

Reading Text Files in Java with Scanner

Using a specified delimiter, the Scanner class divides a file's content into sections and reads each section one at a time. This method works well when reading material that is divided up by a delimiter. The Scanner class, for instance, is excellent for scanning lists of strings or numbers that are separated by commas. Whitespace is the Scanner class's default delimiter. The delimiter can, however, be changed to a different character or regular expression. In order to transform content into different types, it also has a variety of methods, including next(), nextInt(), nextLine(), and nextByte().

import java.io.IOException;
import java.util.Scanner;
import java.io.File;

public class FileReaderWithScanner {

    public static void main(String[] a) throws IOException{
        String file = "src/file.txt";
        Scanner scanner = new Scanner(new File(file));
        scanner.useDelimiter(" ");

        while(scanner.hasNext()){
            String next = scanner.next();
            System.out.println(next);
        }
        scanner.close();
    }
}

write your code here: Coding Playground

In the aforementioned example, the delimiter is set to whitespace, and the next() method is used to read the next section of the content.

Reading an Entire File

Without using a loop, you can read the whole file at once by using the Scanner class. For this, you must supply "Z" as the delimiter.

scanner.useDelimiter("\\Z");
System.out.println(scanner.next());
scanner.close();

Note: The Scanner class is not synchronized and therefore, not thread-safe.

Conclusion

As you learned in this article, Java provides a variety of ways for reading text files that you may select from depending on the task at hand. BufferedReader allows you to read big files line- by-line. Use the Scanner class if you wish to read a file whose contents are divided by a delimiter. Additionally, you may read both tiny and big files using the Java NIO Files class.