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:
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:
while((currentLine = reader.readLine()) != null){//while there is content on the current line
07
System.out.println(currentLine); // print the current line
08
}
09
}catch(IOException ex){
10
ex.printStackTrace(); //handle an exception here
11
}
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:
for(String content:contents){//for each line of content in contents
08
System.out.println(content);// print the line
09
}
10
11
}catch(IOException ex){
12
ex.printStackTrace();//handle exception here
13
}
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:
Files.lines(path).forEach(System.out::println);//print each line
5
6
} catch(IOException ex) {
7
ex.printStackTrace();//handle exception here
8
}
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.
.filter(line -> line.startsWith("Love")) // this line filters any line out which does not meet the condition
06
.forEach(System.out::println);//print each line
07
08
} catch(IOException ex) {
09
ex.printStackTrace();//handle exception here
10
}
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 load data from a CSV file in Java program by using BufferedReader class from java.io package. You can read the file line by line and convert each line into an object representing that data. Actually there are couple of ways to read or parse CSV file in Java e.g. you can use a third party library like Apache commons CSV or you can use Scanner class, but in this example we will use traditional way of loading CSV file using BufferedReader.
Here are the steps to load data from CSV file in Java without using any third party library :
Open CSV file using FileReader object
Create BufferedReader from FileReader
Read file line by line using readLine() method
Split each line on comma to get an array of attributes using String.split() method
Create object of Book class from String array using new Book()
Add those object into ArrayList using add() method
Return the List of books to caller
And here is our sample CSV file which contains details of my favorite books. It's called books.csv, each row represent a book with title, price and author information. First column is title of book, second column is price and third column is author of the book.
Effective Java,42,Joshua Bloch Head First Java,39,Kathy Sierra Head First Design Pattern,44,Kathy Sierra Introduction to Algorithm,72,Thomas Cormen
Step by Step guide to load a CSV file in Java
Let's go through each steps to find out what they are doing and how they are doing :
Reading the File To read the CSV file we are going to use a BufferedReader in combination with a FileReader. FileReader is used to read a text file in platform's default character encoding, if your file is encoded in other character encoding then you should use InputStreamReader instead of FileReader class. We will read one line at a time from the file using readLine() method until the EOF (end of file) is reached, in that case readLine() will return a null.
Split comma separated String We take the string that we read from CSV file and split it up using the comma as the 'delimiter' (because its a CSV file). This creates an array with the all the columns of CSV file as we want, however values are still in Strings, so we need to convert them into proper type e.g. prices into float type as discussed in my post how to convert String to float in Java. Once we got all the attribute values, we create an object of Book class by invoking constructor of book as new Book() and pass all those attributes. Once we Book object then we simply add them to our ArrayList.
Java Program to load data from CSV file
Here is our full program to read a CSV file in Java using BufferedReader. It's good example of how to read data from file line by line, split string using a delimiter and how to create object from a String array in Java. Once you load data into program you can insert into database, or you can persist into some other format or you can send it over network to other JVM.
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.nio.charset.StandardCharsets;
importjava.nio.file.Files;
importjava.nio.file.Path;
importjava.nio.file.Paths;
importjava.util.ArrayList;
importjava.util.List;
/**
* Simple Java program to read CSV file in Java. In this program we will read
* list of books stored in CSV file as comma separated values.
*
* @author WINDOWS 8
*
*/publicclassCSVReaderInJava {
publicstaticvoidmain(String... args) {
List<Book> books = readBooksFromCSV("books.txt");
// let's print all the person read from CSV filefor (Book b : books) {
System.out.println(b);
}
}
privatestaticList<Book>readBooksFromCSV(String fileName) {
List<Book> books =newArrayList<>();
Path pathToFile =Paths.get(fileName);
// create an instance of BufferedReader// using try with resource, Java 7 feature to close resourcestry (BufferedReader br =Files.newBufferedReader(pathToFile,
StandardCharsets.US_ASCII)) {
// read the first line from the text fileString line = br.readLine();
// loop until all lines are readwhile (line !=null) {
// use string.split to load a string array with the values from// each line of// the file, using a comma as the delimiterString[] attributes = line.split(",");
Book book = createBook(attributes);
// adding book into ArrayList
books.add(book);
// read next line before looping// if end of file reached, line would be null
line = br.readLine();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return books;
}
privatestaticBookcreateBook(String[] metadata) {
String name = metadata[0];
int price =Integer.parseInt(metadata[1]);
String author = metadata[2];
// create and return book of this metadatareturnnewBook(name, price, author);
}
}
classBook {
privateString name;
privateint price;
privateString author;
publicBook(String name, int price, String author) {
this.name = name;
this.price = price;
this.author = author;
}
publicStringgetName() {
return name;
}
publicvoidsetName(String name) {
this.name = name;
}
publicintgetPrice() {
return price;
}
publicvoidsetPrice(int price) {
this.price = price;
}
publicStringgetAuthor() {
return author;
}
publicvoidsetAuthor(String author) {
this.author = author;
}
@OverridepublicStringtoString() {
return"Book [name="+ name +", price="+ price +", author="+ author
+"]";
}
}
OutputBook [name=EffectiveJava, price=42, author=JoshuaBloch]
Book [name=HeadFirstJava, price=39, author=KathySierra]
Book [name=HeadFirstDesignPattern, price=44, author=KathySierra]
Book [name=Introduction to Algorithm, price=72, author=ThomasCormen]
That's all about how to load CSV file in Java without using any third party library. You have learned how to use BufferedReader to read data from CSV file and then how to split comma separated String into String array by using String.split() method. Though you can do it even more easily by using third party library like Apache commons CSV, but knowing how to do it using pure Java will help you to learn key classes form JDK.
If you like this tutorial and interested to learn more about how to deal with files and directory in Java, you can checkout following Java IO tutorial :
How to read Excel File in Java using Apache POI? [example]
How to append data into an existing file in Java? [example]
This example shows you how to use Stream to filter content, convert the entire content to upper case and return it as a List.
TestReadFile2.java
package com.mkyong.java8;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;import java.util.stream.Stream;publicclassTestReadFile2{publicstaticvoidmain(String args[]){
String fileName ="c://lines.txt";
List<String> list =newArrayList<>();try(Stream<String> stream = Files.lines(Paths.get(fileName))){//1. filter line 3//2. convert all content to upper case//3. convert it into a List
list = stream
.filter(line ->!line.startsWith("line3")).map(String::toUpperCase).collect(Collectors.toList());}catch(IOException e){
e.printStackTrace();}
list.forEach(System.out::println);}}
Output
LINE1
LINE2
LINE4
LINE5
3. BufferedReader + Stream
A new method lines() has been added since 1.8, it lets BufferedReader returns content as Stream.
TestReadFile3.java
package com.mkyong.java8;import java.io.BufferedReader;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;publicclassTestReadFile3{publicstaticvoidmain(String args[]){
String fileName ="c://lines.txt";
List<String> list =newArrayList<>();try(BufferedReader br = Files.newBufferedReader(Paths.get(fileName))){//br returns as stream and convert it into a List
list = br.lines().collect(Collectors.toList());}catch(IOException e){
e.printStackTrace();}
list.forEach(System.out::println);}}
Output
line1
line2
line3
line4
line5
4. Classic BufferedReader And Scanner
Enough of Java 8 and Stream, let revisit the classic BufferedReader (JDK1.1) and Scanner (JDK1.5) examples to read a file line by line, it is working still, just developers are moving toward Stream.