In my previous articles, I wrote about reading and writing text as well as binary files in Java using legacy Java I/O API. In this article, you will learn how to read and write files using the non-blocking new I/O API (NIO).

The legacy API (classes in the java.io.* package) is good for performing low-level binary I/O operations such as reading and writing just one byte at a time. On the other hand, the NIO API (classes in the java.nio.* package) is faster than the old I/O API and more suitable for reading and writing the whole file at once.

Reading Files

The NIO API Files class provides several static methods to read a file as a bytes array, a list of strings, or as a stream.

Files.readAllBytes() Method

The following example demonstrates how you can use the Files.readAllBytes() static method to read a text file into an array of bytes at once:

try {
    // read all bytes
    byte[] bytes = Files.readAllBytes(Paths.get("input.txt"));

    // convert bytes to string
    String content = new String(bytes);
    
    // print contents
    System.out.println(content);

} catch (IOException ex) {
    ex.printStackTrace();
}

Files.readAllLines() Method

The Files.readAllLines() method can be used to read a text file line by line into a List of String, as shown below:

try {
    // read all lines
    List<String> lines = Files.readAllLines(Paths.get("input.txt"));

    // print all lines
    for (String line : lines) {
        System.out.println(line);
    }

} catch (IOException ex) {
    ex.printStackTrace();
}

By default, Files.readAllLines() uses UTF-8 character encoding. But you can specify a different character encoding like below:

List<String> lines = Files.readAllLines(Paths.get("input.txt"), StandardCharsets.UTF_16);

Files.lines() Method

The Files.lines() method allows us to read a file line by line by using Java 8 Stream API. The stream can then be mapped or filtered out. Here is an example that uses Files.lines() to read a file line by line, filters empty lines and removes whitespace at the end of each line:

try {
    // initialize lines stream
    Stream<String> stream = Files.lines(Paths.get("input.txt"));

    // apply filters and print all ines
    stream.map(String::trim)
            .filter(l -> !l.isEmpty())
            .forEach(System.out::println);

    // close the stream
    stream.close();

} catch (IOException ex) {
    ex.printStackTrace();
}

If you are reading a file with encoding other than the default character encoding of the operating system, just pass it as a second parameter:

Stream<String> stream = Files.lines(Paths.get("input.txt"), StandardCharsets.UTF_8);

Writing Files

To write a text, you can use the Files.write() the static method from the NIO API:

try {
    // data to write
    String contents = "Hey, there!\nWhat's up?";

    // write to file
    Files.write(Paths.get("output.txt"), contents.getBytes());

} catch (IOException ex) {
    ex.printStackTrace();
}

With Files.write(), you can also specify a file operation. The following example appends data to an existing text file:

try {
    // data to write
    String contents = "Weldone!";

    // append to file
    Files.write(Paths.get("output.txt"), contents.getBytes(), StandardOpenOption.APPEND);

} catch (IOException ex) {
    ex.printStackTrace();
}

To explicitly specify an encoding scheme while writing a text file, you can do the following:

try {
    // data to write
    List<String> contents = Arrays.asList("Hey, there", "How are you doing?");

    // write to file
    Files.write(Paths.get("output.txt"), contents,
            StandardCharsets.UTF_8,
            StandardOpenOption.CREATE);

} catch (IOException ex) {
    ex.printStackTrace();
}

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.