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)