How to read a CSV file in Java | with examples

A CSV file is a plain text file. Each line of the file represents a row of data. Fields in each row are separated by a delimiter, in this case ,.

data.txt

First,Last,Age
John,Doe,23
Sam,Smith,40
Jan,Miller,18
The first row of a CSV file is often a "header" row:
First,Last,Age
Notice how our sample file includes a header row. The header row describes what each column represents for a given row.

Read a CSV file in Java - Basic Example

import java.io.BufferedReader;
import java.io.FileReader;

public class CsvReader {
    public static void main(String[] args) {
       String file = "resources/data.txt";
       String line;
        try (BufferedReader br =
                     new BufferedReader(new FileReader(file))) {
            while((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

output

First,Last,Age
John,Doe,23
Sam,Smith,40
Jan,Miller,18

Notice how we use the BufferedReader method readLine() to loop through each line of our file.

If you don't know what a BufferedReader is, be sure to check out FileReader vs BufferedReader vs Scanner.

Also notice how we pass a BufferedReader instance br as an argument to our try...catch block. This is considered a try-with-resources block.

The try-with-resources block is new in Java SE 7+. This is the preferred way to handle I/O. Since the BufferedReader class implements java.lang.AutoCloseable, it will automatically close the resource regardless of how the try statement executes.

Using the try-with-resources block, we don't need to worry about manually closing the resource.

Alternatively, we could manually close the BufferedReader with:

finally {
    if (br != null) br.close();
}

You would need to manually close the resource only if you're using older versions of Java that don't support try-with-resources.

Read CSV File into ArrayList

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CsvReader {
    public static void main(String[] args) {
       String file = "resources/data.txt";
       String delimiter = ",";
       String line;
       List<List<String>> lines = new ArrayList();
        try (BufferedReader br =
                     new BufferedReader(new FileReader(file))) {
            while((line = br.readLine()) != null){
                List<String> values = Arrays.asList(line.split(delimiter));
                lines.add(values);
            }
            lines.forEach(l -> System.out.println(l));
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

output

[First, Last, Age]
[John, Doe, 23]
[Sam, Smith, 40]
[Jan, Miller, 18]

Notice how we use the same readLine() method to iterate over each row in the file.

We convert each row to an array by splitting the line based on a delimiter,.

This creates an array of arrays. Each row of data is added to the lines array.

Parse a CSV File using Scanner

As an alternative to BufferedReader, we can use Scanner to iterate over the CSV file...

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;


public class CsvReader {
    public static void main(String[] args) {
       String file = "resources/data.txt";
       String delimiter = ",";
       String line;
       List<List<String>> lines = new ArrayList();
        try (Scanner s =
                     new Scanner(new File(file))) {
            while(s.hasNext()){
                line = s.next();
                List values = Arrays.asList(line.split(delimiter));
                lines.add(values);
            }
            lines.forEach(l -> System.out.println(l));
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

Scanner provides a similar method hasNext() for determining the end of the file. Using the s.next() method we are able to get the data for a given line.

Wondering when to use FileReader vs BufferedReader vs Scanner?

Read a CSV File in Java with a Header

import java.io.BufferedReader;
import java.io.FileReader;


public class CsvReader {
    public static void main(String[] args) {
       String file = "resources/data.txt";
       String headers;
       String line;
        try (BufferedReader br =
                     new BufferedReader(new FileReader(file))) {
            headers = br.readLine();
            while((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

Remember that the headers are simply the first row of the CSV file. We set the headers to a variable headers by reading the first line..

headers = br.readLine()

The better way...using Apache Commons CSV

These examples have all used native Java classes. While these are all viable solutions, libraries like Apache Commons CSV have made reading CSV files much easier...

Using Maven, you can add the Apache Commons CSV library as a dependency to your pom.xml file...

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.6</version>
</dependency>
This adds the Apache Commons CSV library so you can import what you need...

Read a CSV File by Column Name

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.BufferedReader;
import java.io.FileReader;


public class CsvReader {
    public static void main(String[] args) {
        try(
                BufferedReader br = new BufferedReader(new FileReader("resources/data.txt"));
                CSVParser parser = CSVFormat.DEFAULT.withDelimiter(',').withHeader().parse(br);
                ) {
            for(CSVRecord record : parser) {
                System.out.println(record.get("First"));
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

output

John,
Sam,
Jan

Notice how we can specify headers via the withHeader() method. This makes it easy to work with headers as we can now read the CSV file by column name.

Also notice how the first row of the file is correctly ignored by specifying withHeader().

By using the Apache Commons CSV library we can more easily specify delimiters, formats, and headers. For these reasons, it's generally preferred to use a library like Apache Commons for reading CSV files.

Your thoughts?

|

wow great explanation huge thanks!

|

yes very helpful..glad that they explore the performance costs of the choice you make with some of these utils.

|

Apache Commons is a great library and should be used. BUT i will say it's good to know how to read a csv file without these "helpers" first. You will be much better off in the long run.