Core Java

Java Nio Read File Example

With this example we are going to demonstrate how to use the Non-blocking I/O API, or NIO.2 API (NIO API) for short, to read the contents of a file. The examples in this article are compiled and run in a Mac OS unix environment.

Please note that Java SE 8 is required to run the code in this article.

1. Introduction to the NIO API

The NIO.2 API was introduced in Java 7 as a replacement for the java.io.File class. It provides a flexible, and intuitive API for use with files.

2. Creating a NIO Path

In order to read a file from the file system we must first create a Path to the file.  A Path object is a hierarchical representation of the path on a system to the file or directory. The java.nio.file.Path interface is the primary entry point for working with the NIO 2 API.

The easiest way to create a Path Object is to use the java.nio.files.Paths factory class. The class has a static get() method which can be used to obtain a reference to a file or directory. The method accepts either a string, or a sequence of strings(which it will join to form a path) as parameters. A java.nio.file.Path , like a File, may refer to either an absolute or relative path within the file system.  This is displayed in the following examples:

Path p1 = Paths.get("cats/fluffy.jpg");
Path p2 = Paths.get("/home/project");
Path p3 = Paths.get("/animals", "dogs", "labradors");

In the above:

  • p1 creates a relative reference to a file in the current working directory.
  • p2 creates a reference to an absolute directory in a Unix based system.
  • p3 creates a reference to the absolute directory /animals/dogs/labradors

3. Reading files with the NIO API

Once we have a Path Object we are able to execute most of the operations that were previously possible with java.io.File.

3.1 Using NIO API with newBufferedReader()

The NIO.2 API has methods for reading files using java.io streams.  The Files.newBufferedReader(Path,Charset) reads the file found at the Path location, using the specified Charset for character encoding. Here’s an example:

Path path = Paths.get("src/main/resources/shakespeare.txt");
    try(BufferedReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"))){

      
      String currentLine = null;
      while((currentLine = reader.readLine()) != null){//while there is content on the current line
        System.out.println(currentLine); // print the current line
      }
    }catch(IOException ex){
      ex.printStackTrace(); //handle an exception here
    }

3.2 Using NIO API with readAllLines()

Another option is to use the Files.readAll() method, which will read the contents of a file and return them as an ordered list of strings. Here’s an example of this method:

    Path path = Paths.get("src/main/resources/shakespeare.txt");
    try{

      List contents = Files.readAllLines(path);

      //Read from the stream
      for(String content:contents){//for each line of content in contents
        System.out.println(content);// print the line
      }

      }catch(IOException ex){
      ex.printStackTrace();//handle exception here
    }

NOTE: The readAllLines() method first commits the contents of the file to memory, as a result you may encounter an OutOfMemoryError if there is too much content.

3.3 Using NIO API with streams

With Java 8 came the introduction of streams in place of the previously used methods of iteration. This makes it easy to lazily load lines from a file, using memory in a piecemeal fashion, and therefore preventing the OutOfMemoryError which was mentioned above. The example below shows how to make use of streams to achieve this:

    Path path = Paths.get("src/main/resources/shakespeare.txt");
    try {

      Files.lines(path).forEach(System.out::println);//print each line

    } catch (IOException ex) {
      ex.printStackTrace();//handle exception here
    }

Stream operations can be chained together into pipelines, which can make for some very powerful, declarative and concise code. For example, making use of the filter() operation on the above code in combination with the NIO API, allows us to to begin to analyse the contents of the file with ease.

    Path path = Paths.get("src/main/resources/shakespeare.txt");
    try {

      Files.lines(path)
           .filter(line -> line.startsWith("Love")) // this line filters any line out which does not meet the condition
          .forEach(System.out::println);//print each line

    } catch (IOException ex) {
      ex.printStackTrace();//handle exception here
    }

The example above shows how simply we are able to begin looking at Shakespeare’s lexical choices.

4. Summary

In this article we’ve introduced you several ways to use the NIO API to read a file from your file system. Along the way we’ve touched upon the Path object and let you know the benefits of using one method over another.

5. Download the Source Code

Below you can download the file read examples shown above:

Download
You can download the full source code of this example here: NIO API Read File Example

Aaron Witter

Aaron is a self-taught Certified Oracle Java programmer, with experience delivering high quality Java applications for a variety of UK Government Departments. Aaron has worked on projects ranging from the overhaul of the National Statistics website to delivering a portal for quality management in the National Health Service.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button