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:
You can download the full source code of this example here: NIO API Read File Example