Week 124 — How can one read and write CSV files in Java?

Question of the Week #124
How can one read and write CSV files in Java?
3 Replies
Talha Tahir
Talha Tahir2w ago
Reading and writing CSV files is possible both using the standard libraries (e.g. java.io) and using external libraries. For example, we might want to save the following record in a CSV file and read it again:
record Person(String firstName, String lastName, int age) {}
record Person(String firstName, String lastName, int age) {}
This can be done using the JDK standard libraries by creating a Writer and saving it line by line:
public void savePeople(List<Person> people) throws IOException {
try(BufferedWriter bw = Files.newBufferedWriter(Path.of("people.csv"))) {
bw.write("First name,Last name,Age");
bw.newLine();

for(Person person : people) {
bw.write(person.firstName());
bw.write(",");
bw.write(person.lastName());
bw.write(",");
bw.write(String.valueOf(person.age()));
bw.newLine();
}
}
}
public void savePeople(List<Person> people) throws IOException {
try(BufferedWriter bw = Files.newBufferedWriter(Path.of("people.csv"))) {
bw.write("First name,Last name,Age");
bw.newLine();

for(Person person : people) {
bw.write(person.firstName());
bw.write(",");
bw.write(person.lastName());
bw.write(",");
bw.write(String.valueOf(person.age()));
bw.newLine();
}
}
}
To read a CSV file corresponding to the code before, the file can be read line by line and split by commas:
public List<Person> readPeople() throws IOException {
List<Person> people = new ArrayList<>();
try(BufferedReader br = Files.newBufferedReader(Path.of("people.csv"))){
br.readLine(); // skip header

String line;
while((line = br.readLine()) != null) {
String[] split = line.split(",");
if(split.length != 3) {
throw new IOException("invalid number of columns");
}
people.add(new Person(split[0], split[1], Integer.parseInt(split[2])));
}
}
return Collections.unmodifiableList(people);
}
public List<Person> readPeople() throws IOException {
List<Person> people = new ArrayList<>();
try(BufferedReader br = Files.newBufferedReader(Path.of("people.csv"))){
br.readLine(); // skip header

String line;
while((line = br.readLine()) != null) {
String[] split = line.split(",");
if(split.length != 3) {
throw new IOException("invalid number of columns");
}
people.add(new Person(split[0], split[1], Integer.parseInt(split[2])));
}
}
return Collections.unmodifiableList(people);
}
However, this code does not address the possibility of commas, quoting, line breaks or backslashes in the input. While it is possible to add validation for that, it is also possible to use external libraries for this task.
Talha Tahir
Talha Tahir2w ago
To write such a CSV file with Apache Commons CSV, one can call the printRecord on the CSVFormat class for every entry:
private CSVFormat format = CSVFormat.DEFAULT
.builder()
.setHeader("First name", "Last name", "Age")
.build();
private CSVFormat format = CSVFormat.DEFAULT
.builder()
.setHeader("First name", "Last name", "Age")
.build();
public void savePeopleApacheCommons(List<Person> people) throws IOException {
try(CSVPrinter printer = format.print(Files.newBufferedWriter(Path.of("people.csv")))) {
for(Person person : people) {
printer.printRecord(person.firstName(), person.lastName(), person.age());
}
}
}
public void savePeopleApacheCommons(List<Person> people) throws IOException {
try(CSVPrinter printer = format.print(Files.newBufferedWriter(Path.of("people.csv")))) {
for(Person person : people) {
printer.printRecord(person.firstName(), person.lastName(), person.age());
}
}
}
It can then be read using the CSVFormat.parse method:
public List<Person> readPeopleApacheCommons() throws IOException {
List<Person> people = new ArrayList<>();
try(BufferedReader br = Files.newBufferedReader(Path.of("people.csv"))){
for(CSVRecord entry : format.parse(reader)) {
people.add(entry.get("First name"), entry.get("Last name"), Integer.parseInt(entry.get("Age")));
}
return people;
}
}
public List<Person> readPeopleApacheCommons() throws IOException {
List<Person> people = new ArrayList<>();
try(BufferedReader br = Files.newBufferedReader(Path.of("people.csv"))){
for(CSVRecord entry : format.parse(reader)) {
people.add(entry.get("First name"), entry.get("Last name"), Integer.parseInt(entry.get("Age")));
}
return people;
}
}
📖 Sample answer from dan1st
Talha Tahir
Talha Tahir2w ago
It could be done using BufferedReader, FileReader for reading CSV And BufferedWriter, FileWriter for writing CSV
Submission from talhah_tahir

Did you find this page helpful?