This tutorial covers CSV file handling using both raw Java and the OpenCSV library.
1. Using Raw Java
Reading CSV Files with Raw Java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class RawJavaCSVReader {
public static void main(String[] args) {
String csvFile = "data.csv";
String line = "";
String csvDelimiter = ","; // CSV files typically use comma as delimiter
List<String[]> data = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
// Read the header line (first line)
String headerLine = br.readLine();
if (headerLine != null) {
String[] headers = headerLine.split(csvDelimiter);
System.out.println("Headers: " + String.join(", ", headers));
}
// Read data lines
while ((line = br.readLine()) != null) {
// Split the line by comma, handling quoted fields
String[] values = parseCSVLine(line, csvDelimiter);
data.add(values);
// Print the row
System.out.println("Row: " + String.join(" | ", values));
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Total rows read: " + data.size());
}
/**
* Parses a CSV line, handling quoted fields that may contain commas
* @param line the CSV line to parse
* @param delimiter the delimiter character
* @return array of field values
*/
private static String[] parseCSVLine(String line, String delimiter) {
List<String> values = new ArrayList<>();
StringBuilder currentValue = new StringBuilder();
boolean inQuotes = false;
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == '"') {
// Handle quotes - either start/end of quoted field or escaped quote
if (inQuotes && i < line.length() - 1 && line.charAt(i + 1) == '"') {
// Escaped quote inside quoted field
currentValue.append('"');
i++; // Skip the next quote
} else {
// Toggle quote state
inQuotes = !inQuotes;
}
} else if (c == delimiter.charAt(0) && !inQuotes) {
// Found delimiter outside quotes - end of field
values.add(currentValue.toString());
currentValue = new StringBuilder();
} else {
// Regular character
currentValue.append(c);
}
}
// Add the last field
values.add(currentValue.toString());
return values.toArray(new String[0]);
}
}
Writing CSV Files with Raw Java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class RawJavaCSVWriter {
public static void main(String[] args) {
String csvFile = "output.csv";
// Sample data
List<String[]> data = Arrays.asList(
new String[]{"Name", "Age", "City", "Email"},
new String[]{"John Doe", "30", "New York", "john@example.com"},
new String[]{"Jane Smith", "25", "London", "jane@example.com"},
new String[]{"Bob Johnson", "35", "Paris", "bob@example.com"}
);
try (BufferedWriter bw = new BufferedWriter(new FileWriter(csvFile))) {
for (String[] row : data) {
// Format each row as CSV
String csvLine = formatAsCSV(row);
bw.write(csvLine);
bw.newLine();
}
System.out.println("CSV file written successfully: " + csvFile);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Formats an array of values as a CSV line
* @param values array of field values
* @return CSV formatted string
*/
private static String formatAsCSV(String[] values) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
String value = values[i];
// Check if value needs quoting (contains comma, quote, or newline)
boolean needsQuotes = value.contains(",") || value.contains("\"") || value.contains("\n");
if (needsQuotes) {
sb.append('"');
// Escape quotes by doubling them
sb.append(value.replace("\"", "\"\""));
sb.append('"');
} else {
sb.append(value);
}
// Add delimiter unless it's the last value
if (i < values.length - 1) {
sb.append(',');
}
}
return sb.toString();
}
}
2. Using OpenCSV
Setting Up OpenCSV
Add OpenCSV dependency to your project:
Maven:
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.7.1</version>
</dependency>
Gradle:
implementation 'com.opencsv:opencsv:5.7.1'
Reading CSV Files with OpenCSV
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
public class OpenCSVReaderExample {
public static void main(String[] args) {
String csvFile = "data.csv";
try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvFile))
.withSkipLines(0) // Skip lines if needed (e.g., skip header)
.build()) {
// Read all records at once
List<String[]> allData = reader.readAll();
// Process each record
for (int i = 0; i < allData.size(); i++) {
String[] row = allData.get(i);
if (i == 0) {
System.out.println("Headers: " + String.join(", ", row));
} else {
System.out.println("Row " + i + ": " + String.join(" | ", row));
}
}
System.out.println("Total records: " + allData.size());
} catch (IOException | CsvException e) {
e.printStackTrace();
}
}
}
Reading CSV with Custom Settings
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
public class OpenCSVAdvancedReader {
public static void main(String[] args) {
String csvFile = "data.csv";
try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvFile))
.withCSVParser(new com.opencsv.CSVParserBuilder()
.withSeparator(',') // Set custom separator
.withQuoteChar('"') // Set custom quote character
.withEscapeChar('\\') // Set escape character
.build())
.withSkipLines(1) // Skip header line
.build()) {
// Read line by line (better for large files)
String[] nextLine;
int rowCount = 0;
while ((nextLine = reader.readNext()) != null) {
rowCount++;
System.out.println("Row " + rowCount + ": " + String.join(" | ", nextLine));
// Process individual fields
for (int i = 0; i < nextLine.length; i++) {
System.out.println(" Field " + i + ": " + nextLine[i]);
}
}
System.out.println("Total rows processed: " + rowCount);
} catch (IOException | CsvException e) {
e.printStackTrace();
}
}
}
Writing CSV Files with OpenCSV
import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class OpenCSVWriterExample {
public static void main(String[] args) {
String csvFile = "output.csv";
// Sample data
List<String[]> data = Arrays.asList(
new String[]{"Name", "Age", "City", "Email"},
new String[]{"John Doe", "30", "New York", "john@example.com"},
new String[]{"Jane Smith", "25", "London", "jane@example.com"},
new String[]{"Bob Johnson", "35", "Paris", "bob@example.com"}
);
try (CSVWriter writer = new CSVWriter(new FileWriter(csvFile))) {
// Write all records at once
writer.writeAll(data);
System.out.println("CSV file written successfully: " + csvFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Writing CSV with Custom Settings
import com.opencsv.CSVWriter;
import com.opencsv.ICSVWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
public class OpenCSVAdvancedWriter {
public static void main(String[] args) {
String csvFile = "output_custom.csv";
try (CSVWriter writer = new CSVWriter(
new FileWriter(csvFile),
';', // Custom separator (semicolon instead of comma)
ICSVWriter.DEFAULT_QUOTE_CHARACTER,
ICSVWriter.DEFAULT_ESCAPE_CHARACTER,
ICSVWriter.DEFAULT_LINE_END)) {
// Write header
writer.writeNext(new String[]{"ID", "Product", "Price", "Description"});
// Write data rows
writer.writeNext(new String[]{"1", "Laptop", "999.99", "High-performance laptop"});
writer.writeNext(new String[]{"2", "Mouse", "25.50", "Wireless optical mouse"});
writer.writeNext(new String[]{"3", "Keyboard", "75.00", "Mechanical gaming keyboard"});
// Write a row with special characters that need quoting
writer.writeNext(new String[]{"4", "Monitor, 24\"", "200.00", "24-inch monitor, with stand"});
System.out.println("Custom CSV file written successfully: " + csvFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Mapping CSV to Java Objects with OpenCSV
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
// Define a Java bean class that matches CSV structure
class Person {
private String name;
private int age;
private String city;
private String email;
// Default constructor required by OpenCSV
public Person() {}
// Parameterized constructor
public Person(String name, int age, String city, String email) {
this.name = name;
this.age = age;
this.city = city;
this.email = email;
}
// Getters and setters (required by OpenCSV)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", city='" + city + "', email='" + email + "'}";
}
}
public class OpenCSVBeanExample {
public static void main(String[] args) {
String csvFile = "people.csv";
try (FileReader reader = new FileReader(csvFile)) {
// Create mapping strategy
HeaderColumnNameMappingStrategy<Person> strategy = new HeaderColumnNameMappingStrategy<>();
strategy.setType(Person.class);
// Create CSV to bean converter
CsvToBean<Person> csvToBean = new CsvToBeanBuilder<Person>(reader)
.withMappingStrategy(strategy)
.withIgnoreLeadingWhiteSpace(true)
.build();
// Convert CSV to list of Person objects
List<Person> people = csvToBean.parse();
// Process the objects
for (Person person : people) {
System.out.println(person);
// You can now work with Person objects instead of raw arrays
if (person.getAge() > 30) {
System.out.println(" -> Over 30 years old");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Comparison: Raw Java vs OpenCSV
Raw Java Advantages:
- No external dependencies
- Full control over parsing logic
- Good for simple CSV files
Raw Java Disadvantages:
- Complex to handle edge cases (quoted fields, escaped characters)
- More code to write and maintain
- No built-in support for data mapping
OpenCSV Advantages:
- Handles all CSV edge cases automatically
- Easy to use API
- Support for mapping CSV to Java objects
- Better performance for large files
- Built-in support for different formats and encodings
OpenCSV Disadvantages:
- External dependency
- Less control over low-level parsing
Best Practices
- Always handle exceptions properly - CSV files can have various formatting issues
- Use try-with-resources to ensure files are properly closed
- Validate data - check for null values and data types
- Consider file encoding - specify UTF-8 if working with international characters
- Use OpenCSV for production code - it handles edge cases better than custom code
- For large files, read line by line instead of loading entire file into memory
Top comments (0)