Read a CSV File in Java
Problem
A CSV (comma-separated values) file stores a table as text: one row per line, with commas between the columns and often a header row first.
Read a CSV of sales by region, print each region's units, and compute the total units and revenue.
Java Program
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ReadCsvFile {
public static void main(String[] args) throws IOException {
Path csv = Paths.get("sales.csv");
Files.writeString(csv, "region,units,price\nNorth,12,250\nSouth,8,300\nEast,15,200\n");
int totalUnits = 0;
long revenue = 0;
try (BufferedReader reader = Files.newBufferedReader(csv)) {
String header = reader.readLine(); // skip the column names
String line;
while ((line = reader.readLine()) != null) {
String[] cols = line.split(",");
int units = Integer.parseInt(cols[1].trim());
int price = Integer.parseInt(cols[2].trim());
totalUnits += units;
revenue += (long) units * price;
System.out.println(cols[0] + ": " + units + " units");
}
System.out.println("Columns: " + header);
}
System.out.println("Total units: " + totalUnits + ", revenue: " + revenue);
Files.delete(csv);
}
}Output
Core Logic
Each line is one record: skip the header, split the rest on commas, convert the numeric columns, and accumulate totals.
- 1The program writes a sample
sales.csvfirst, so it can run anywhere. - 2The first
readLine()reads and keeps the header row. - 3Each later line is split with
split(","), and columns 1 and 2 are parsed as numbers. - 4Units are added to a total, and units × price is added to the revenue.
Key Point: A plain split(",") breaks on commas inside quoted fields such as "Delhi, NCR"; real-world CSV needs a proper parser.
Why: Each of the n lines is read and parsed once, holding only the current line of length L.
Key Concepts
Approach 2: Using Files.lines()
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class ReadCsvFileStream {
public static void main(String[] args) throws IOException {
Path csv = Paths.get("sales.csv");
Files.writeString(csv, "region,units,price\nNorth,12,250\nSouth,8,300\nEast,15,200\n");
try (Stream<String> lines = Files.lines(csv)) {
long revenue = lines.skip(1) // drop the header row
.map(line -> line.split(","))
.mapToLong(c -> Long.parseLong(c[1]) * Long.parseLong(c[2]))
.sum();
System.out.println("Revenue: " + revenue);
}
Files.delete(csv);
}
}
Output
Core Logic
A stream over the file's lines can skip the header and compute the revenue in one pipeline.
- 1
Files.lines(csv)streams the lines lazily inside try-with-resources. - 2
skip(1)drops the header row. - 3Each row is split and mapped to units × price, and
sum()adds them up.
Key Point: The stream holds the file open until it's closed, so always use it inside try-with-resources.
Why: Lines are read lazily, one at a time.
Key Concepts
Interview Questions
How do you handle quoted fields that contain commas?
Use a CSV library such as OpenCSV or Apache Commons CSV, or a regex that splits only on commas outside quotes — a simple split(",") can't do it.
What if a numeric column is empty or invalid?
Integer.parseInt throws NumberFormatException. Validate or catch it per row, so one bad line doesn't stop the whole import.