### CSV File with Simple Comments Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/handle-comments.mdx Illustrates a basic CSV file structure where lines starting with '#' are treated as comments. ```plaintext #This is a comment field 1,field 2,field 3 ``` -------------------------------- ### Verify FastCSV Release Artifacts with GPG Source: https://github.com/osiegmar/fastcsv/blob/main/SECURITY.md Use these GPG commands to import the public key and verify the signature of a downloaded fastcsv JAR artifact. Ensure you have GPG installed and the KEYS file available. ```bash gpg --import KEYS ``` ```bash gpg --verify fastcsv-.jar.asc fastcsv-.jar ``` -------------------------------- ### Read CSV Records Sequentially Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Iterate over CSV records in a file and print them to the console using CsvReader. This example reads records as CsvRecord objects. ```java Path file = Path.of("input.csv"); try (CsvReader csv = CsvReader.builder().ofCsvRecord(file)) { csv.forEach(System.out::println); } ``` -------------------------------- ### Empty and Quoted Empty Fields Example Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Illustrates the difference between empty fields and quoted empty fields in CSV data. This is relevant for handling null values, especially for PostgreSQL compatibility. ```csv 1,,fooCRLF 2,"",barCRLF ``` -------------------------------- ### Multiple Fields Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Examples of CSV lines with multiple fields, including quoted fields and fields containing commas. ```text ^___,___$ ^___,___, ^"___",____$^___ ^"___,___"$^___ ``` -------------------------------- ### Write CSV File with FastCSV Source: https://github.com/osiegmar/fastcsv/blob/main/README.md Demonstrates how to write records to a CSV file using FastCSV. Ensure the output file path is correctly specified. This example uses a try-with-resources statement for automatic resource management. ```java try (CsvWriter csv = CsvWriter.builder().build(Path.of("output.csv"))) { csv .writeRecord("header 1", "header 2") .writeRecord("value 1", "value 2"); } ``` -------------------------------- ### Ignore Comment Directive Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Demonstrates the use of COMMENT_NONE to prevent lines starting with '#' from being treated as comments. ```text ^#"___$^___" ^#"___$^___" COMMENT_NONE ``` -------------------------------- ### Commented Lines Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Illustrates how lines starting with '#' are treated as comments and are ignored by the scanner. ```text ^___$^#___$^___ ^___$^#___"$^___ ^#___ ^#___$ ``` -------------------------------- ### Read CSV Records with Headers Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Read CSV files with headers using CsvReader and access fields by name. This example reads records as NamedCsvRecord objects. ```java Path file = Path.of("input.csv"); try (CsvReader csv = CsvReader.builder().ofNamedCsvRecord(file)) { csv.forEach(rec -> System.out.println(rec.getField("foo"))); } ``` -------------------------------- ### Read CSV File with FastCSV Source: https://github.com/osiegmar/fastcsv/blob/main/README.md Shows how to read records from a CSV file into CsvRecord objects using FastCSV. The `ofCsvRecord` method is used for parsing. This example iterates over each record and prints it to the console. It also utilizes a try-with-resources statement. ```java try (CsvReader csv = CsvReader.builder().ofCsvRecord(Path.of("input.csv"))) { csv.forEach(IO::println); } ``` -------------------------------- ### Terminated Records Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Shows examples of records that are properly terminated by a newline character. ```text ^___$ ^___$^$ ``` -------------------------------- ### Reading CSV with Comments (Java) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/handle-comments.mdx Example of reading a CSV file with comments using FastCSV. By default, comments are treated as data. Configure `CommentStrategy` for different handling. ```java import de.siegmar.fastcsv.reader.CsvReader; import de.siegmar.fastcsv.reader.CsvParser; import de.siegmar.fastcsv.reader.CommentStrategy; import java.io.IOException; import java.io.StringReader; import java.util.List; public class ExampleCsvReaderWithComments { public static void main(String[] args) throws IOException { String csvData = "#This is a comment\n" + "field1,field2\n" + "value1,value2\n" + "#Another comment\n" + "value3,value4"; // Default behavior: comments are treated as data try (CsvParser parser = CsvReader.builder().build(new StringReader(csvData))) { List row; System.out.println("--- Default behavior (comments as data) ---"); while ((row = parser.nextRow()) != null) { System.out.println(row); } } // Skip comments try (CsvParser parser = CsvReader.builder() .commentCharacter('#') .skipComments(true) .build(new StringReader(csvData))) { List row; System.out.println("\n--- Skipping comments ---"); while ((row = parser.nextRow()) != null) { System.out.println(row); } } // Custom comment character and skip comments String customCommentCsv = "//This is a comment\n" + "field1,field2\n" + "value1,value2"; try (CsvParser parser = CsvReader.builder() .commentCharacter('/') .skipComments(true) .build(new StringReader(customCommentCsv))) { List row; System.out.println("\n--- Custom comment character ('/') and skipping ---"); while ((row = parser.nextRow()) != null) { System.out.println(row); } } } } ``` -------------------------------- ### Writing CSV with Comments (Java) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/handle-comments.mdx Example of writing CSV data with comments using FastCSV. Comments are automatically handled with necessary escaping and line breaks. ```java import de.siegmar.fastcsv.writer.CsvWriter; import de.siegmar.fastcsv.writer.CsvAppender; import java.io.IOException; import java.io.StringWriter; public class ExampleCsvWriterWithComments { public static void main(String[] args) throws IOException { StringWriter stringWriter = new StringWriter(); // Default comment character is '#' try (CsvAppender appender = CsvWriter.builder().build(stringWriter).appender()) { appender.appendComment("This is a comment"); appender.appendField("field1"); appender.appendField("field2"); appender.nextRow(); appender.appendField("value1"); appender.appendField("value2"); appender.nextRow(); appender.appendComment("Another comment"); appender.appendField("value3"); appender.appendField("value4"); appender.nextRow(); } System.out.println("--- CSV with default comments ('#') ---"); System.out.println(stringWriter.toString()); // Custom comment character stringWriter = new StringWriter(); try (CsvAppender appender = CsvWriter.builder().commentCharacter('!').build(stringWriter).appender()) { appender.appendComment("This is a comment with '!'"); appender.appendField("fieldA"); appender.appendField("fieldB"); appender.nextRow(); } System.out.println("\n--- CSV with custom comments ('!') ---"); System.out.println(stringWriter.toString()); } } ``` -------------------------------- ### Quoted Fields Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Examples of how the scanner processes fields enclosed in double quotes, including cases where quotes appear within the data. ```text ^"___$___"$ ^___$^"___" ^___$^"___$___$ ^___$^"___ ``` -------------------------------- ### Update CsvIndex and CsvPage method calls Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md After updating to Java records, many getter methods in CsvIndex and CsvPage have been simplified by removing the 'get' prefix. This change also affects how pages are accessed. ```java CsvIndex csvIndex = yourCodeToBuildTheIndex(); // Simple get-prefix removal - csvIndex.getBomHeaderLength(); + csvIndex.bomHeaderLength(); - csvIndex.getFileSize(); + csvIndex.fileSize(); - csvIndex.getFieldSeparator(); + csvIndex.fieldSeparator(); - csvIndex.getQuoteCharacter(); + csvIndex.quoteCharacter(); - csvIndex.getCommentStrategy(); + csvIndex.commentStrategy(); - csvIndex.getCommentCharacter(); + csvIndex.commentCharacter(); - csvIndex.getRecordCount(); + csvIndex.recordCount(); // Replaced getPageCount() with pages().size() - csvIndex.getPageCount(); + csvIndex.pages().size(); // Replaced getPage(int) with direct access to the pages list - var firstPage = csvIndex.getPage(0); + var firstPage = csvIndex.pages().getFirst(); // Again, simple get-prefix removal - firstPage.getOffset(); + firstPage.offset() - firstPage.getStartingLineNumber(); + firstPage.startingLineNumber(); ``` -------------------------------- ### Read Last Page of CSV Records Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Read CSV records in pages using IndexedCsvReader, useful for UI pagination. This example demonstrates reading the last page. ```java Path file = Path.of("input.csv"); try (IndexedCsvReader csv = IndexedCsvReader.builder().pageSize(10).ofCsvRecord(file)) { CsvIndex index = csv.getIndex(); int lastPage = index.pages().size() - 1; List csvRecords = csv.readPage(lastPage); } ``` -------------------------------- ### Trimming Whitespace from Fields Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Demonstrates using a FieldModifier to trim leading and trailing whitespace from CSV fields. This example prints 'foo' and 'bar' without extra spaces. ```java var handler = CsvRecordHandler.of(c -> c.fieldModifier(FieldModifiers.TRIM)); CsvReader.builder().build(handler, " foo , bar ") .forEach(System.out::println); ``` -------------------------------- ### Reading Fields Spanning Multiple Lines Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Shows an example of a CSV field that spans multiple lines, enclosed in double quotes. FastCSV preserves the end-of-line characters within the field. ```csv "a multi-line field" ``` -------------------------------- ### Read CSV with CsvReader (Basic) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/architecture.md Demonstrates basic usage of CsvReader for reading CSV records from a file. Leverages try-with-resources for automatic file closing. ```java try (CsvReader csv = CsvReader.builder().ofCsvRecord(file)) { csv.forEach(System.out::println); } ``` -------------------------------- ### Write and Read GZIP-Compressed CSV in Java Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/compressed-csv.mdx Demonstrates writing data to a GZIP-compressed CSV file and then reading it back using FastCSV. Ensure GZIPInputStream and GZIPOutputStream are correctly used for compression and decompression. ```java import io.github.csv.CSVReader; import io.github.csv.CSVWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class ExampleCsvCompression { private static final String FILE_NAME = "compressed.csv.gz"; public static void main(String[] args) throws IOException { writeCompressedCsv(); readCompressedCsv(); } private static void writeCompressedCsv() throws IOException { try (OutputStream fos = new FileOutputStream(FILE_NAME); OutputStream gzos = new GZIPOutputStream(fos); CSVWriter writer = new CSVWriter(gzos)) { writer.writeNext("Header1", "Header2", "Header3"); writer.writeNext("Row1Col1", "Row1Col2", "Row1Col3"); writer.writeNext("Row2Col1", "Row2Col2", "Row2Col3"); System.out.println("Successfully wrote compressed CSV to " + FILE_NAME); } } private static void readCompressedCsv() throws IOException { try (InputStream fis = new FileInputStream(FILE_NAME); InputStream gzis = new GZIPInputStream(fis); CSVReader reader = new CSVReader(gzis)) { System.out.println("Reading from compressed CSV file:"); List lines = reader.readAll(); for (String[] line : lines) { for (String field : line) { System.out.print(field + "\t"); } System.out.println(); } } } } ``` -------------------------------- ### Write CSV with CsvWriter (Explicit Configuration) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/architecture.md Demonstrates explicit configuration of CsvWriter with custom field separators and quote characters before building the writer. ```java CsvWriterBuilder builder = CsvWriter.builder() .fieldSeparator(',') .quoteCharacter('"'); try (CsvWriter csv = builder.build(file)) { csv.writeRecord("field 1", "field 2"); } ``` -------------------------------- ### Use Builder Methods for Handler Instantiation Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md Deprecated constructors for CsvRecordHandler, NamedCsvRecordHandler, and StringArrayHandler should be replaced with builder methods. Use `NamedCsvRecordHandler.of()` for default instantiation or `NamedCsvRecordHandler.builder()...build()` for custom configurations. A functional style using `NamedCsvRecordHandler.of(builder -> ...)` is also available. ```java NamedCsvRecordHandler defaultHandler = new NamedCsvRecordHandler(); ``` ```java NamedCsvRecordHandler defaultHandler = NamedCsvRecordHandler.of(); ``` ```java NamedCsvRecordHandler predefinedHeaderWithTrim = new NamedCsvRecordHandler(FieldModifiers.TRIM, "foo", "bar"); ``` ```java NamedCsvRecordHandler predefinedHeaderWithTrim = NamedCsvRecordHandler.builder() .fieldModifier(FieldModifiers.TRIM) .header("foo", "bar") .build(); ``` ```java NamedCsvRecordHandler predefinedHeaderWithTrim = new NamedCsvRecordHandler(FieldModifiers.TRIM, "foo", "bar"); ``` ```java NamedCsvRecordHandler predefinedHeaderWithTrim = NamedCsvRecordHandler.of(builder -> builder .fieldModifier(FieldModifiers.TRIM) .header("foo", "bar") ); ``` -------------------------------- ### Write CSV Record with Comment Character Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md When writing a record, FastCSV encloses the first field in double quotes if it starts with the configured comment character. ```java writeRecord("#foo", "#bar") ``` -------------------------------- ### Configure Comment Handling Strategy Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Use `CsvReaderBuilder.commentStrategy()` to configure how comment lines are handled during reading. Options include NONE, READ, and SKIP. ```java CsvReaderBuilder.commentStrategy(CommentStrategies.NONE) ``` ```java CsvReaderBuilder.commentStrategy(CommentStrategies.READ) ``` ```java CsvReaderBuilder.commentStrategy(CommentStrategies.SKIP) ``` -------------------------------- ### Write CSV with Different Quote Strategies Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/quote-strategies.mdx Demonstrates writing CSV data using various quote strategies provided by FastCSV. This is useful for controlling how fields are enclosed in quotes, which can impact data interpretation. ```java import de.siegmar.fastcsv.writer.*; import java.io.*; import java.util.Arrays; public class ExampleCsvWriterWithQuoteStrategy { public static void main(String[] args) throws IOException { // Example 1: Always quote fields try (Writer writer = new OutputStreamWriter(new FileOutputStream("always_quoted.csv"))) { CsvWriter.builder() .quoteStrategy(QuoteStrategy.ALWAYS) .build(writer) .writeRecord(Arrays.asList("field 1", "field 2", "field 3")); } // Example 2: Quote non-empty fields try (Writer writer = new OutputStreamWriter(new FileOutputStream("quote_non_empty.csv"))) { CsvWriter.builder() .quoteStrategy(QuoteStrategy.NON_EMPTY) .build(writer) .writeRecord(Arrays.asList("field 1", "", "field 3")); } // Example 3: Quote fields only when necessary (default behavior) try (Writer writer = new OutputStreamWriter(new FileOutputStream("quote_minimal.csv"))) { CsvWriter.builder() .quoteStrategy(QuoteStrategy.MINIMAL) .build(writer) .writeRecord(Arrays.asList("field 1", "field, with comma", "field 3")); } // Example 4: Custom quote strategy try (Writer writer = new OutputStreamWriter(new FileOutputStream("custom_quoted.csv"))) { CsvWriter.builder() .quoteStrategy(new QuoteStrategy() { @Override public String apply(String value) { if (value.equals("field 2")) { return '"' + value + '"'; } return value; } }) .build(writer) .writeRecord(Arrays.asList("field 1", "field 2", "field 3")); } } } ``` -------------------------------- ### Configure Limits via Builder Methods Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md Deprecated system properties for configuring maximum fields per record and maximum field size (`fastcsv.max.field.count`, `fastcsv.max.field.size`) have been removed. Use `CsvRecordHandler.builder()` to set `maxFields` and `maxFieldSize`, and `CsvReader.builder()` to set `maxBufferSize`. ```java // Set the maximum number of fields per record System.setProperty("fastcsv.max.field.count", "16384"); ``` ```java CsvRecordHandler handler = CsvRecordHandler.builder() .maxFields(16_384) .maxFieldSize(16_777_216) .build(); ``` ```java // Set the maximum buffer size and maximum field size System.setProperty("fastcsv.max.field.size", "16777216"); ``` ```java CsvReader csvReader = CsvReader.builder() .maxBufferSize(16_777_216) .build(handler, file); ``` -------------------------------- ### Migrate AbstractBaseCsvCallbackHandler buildRecord method Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md When extending AbstractBaseCsvCallbackHandler, the buildRecord method now returns the record directly instead of a RecordWrapper. You must also use getRecordType() to determine if a record is a comment or empty line. ```java @Override - protected RecordWrapper buildRecord() { - if (isComment()) { + protected MyRecord buildRecord() { + if (getRecordType() == RecordType.COMMENT) { // handle comment... } - if (isEmptyLine()) { + if (getRecordType() == RecordType.EMPTY) { // handle empty line... } MyRecord record = new MyRecord(/* ... */); - return wrapRecord(record); + return record; } ``` -------------------------------- ### Map CSV to Java Beans with FastCSV Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/bean-mapping.mdx Demonstrates mapping CSV records to Java beans using FastCSV's stream API. Ensure necessary imports for CSV reading and bean creation. ```java import com.fastcsv.model.NamedCsvRecord; import com.fastcsv.reader.CsvReader; import java.io.IOException; import java.io.StringReader; import java.util.List; import java.util.stream.Collectors; public class ExampleCsvReaderMapping { // Define a simple Java Bean public static class User { private String name; private int age; // Getters and Setters (or use Lombok) 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; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public static void main(String[] args) { String csvData = "name,age\nAlice,30\nBob,25\nCharlie,35"; try (StringReader reader = new StringReader(csvData)) { CsvReader csvReader = new CsvReader(reader); List users = csvReader.stream() .map(record -> { User user = new User(); user.setName(record.getField("name")); user.setAge(Integer.parseInt(record.getField("age"))); return user; }) .collect(Collectors.toList()); // Print the mapped beans users.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } } } ``` -------------------------------- ### Implement new methods for direct CsvCallbackHandler subclasses Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md Directly extending CsvCallbackHandler requires implementing new abstract methods: getRecordType(), getFieldCount(), and setEmpty(). The buildRecord method now returns the record directly. ```java public class MyHandler extends CsvCallbackHandler { + private RecordType recordType = RecordType.DATA; + private int fieldCount; + @Override + protected RecordType getRecordType() { + return recordType; + } + @Override + protected int getFieldCount() { + return fieldCount; + } + @Override + protected void setEmpty() { + recordType = RecordType.EMPTY; + } @Override - protected RecordWrapper buildRecord() { - return new RecordWrapper<>(isComment, isEmpty, fieldCount, record); + protected MyRecord buildRecord() { + return record; } } ``` -------------------------------- ### Handling Empty Lines in CSV Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Demonstrates how to configure FastCSV to either skip or read empty lines. By default, empty lines are skipped. ```java value_1CRLF CRLF value_2CRLF ``` -------------------------------- ### Add FastCSV Dependency (Gradle/Groovy) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Add this dependency to your build.gradle file to include FastCSV in your project. ```groovy // build.gradle dependencies { implementation 'de.siegmar:fastcsv:${version}' } ``` -------------------------------- ### Add FastCSV Dependency (Gradle/Kotlin) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Add this dependency to your build.gradle.kts file to include FastCSV in your project. ```kotlin // build.gradle.kts dependencies { implementation("de.siegmar:fastcsv:${version}") } ``` -------------------------------- ### Read CSV with CsvReader (Explicit Configuration) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/architecture.md Shows explicit configuration of CsvReader with custom field separators and quote characters. Includes setting a no-operation FieldModifier. ```java // Configures a reusable CsvReaderBuilder with default, but explicitly defined settings. CsvReaderBuilder builder = CsvReader.builder() .fieldSeparator(',') .quoteCharacter('"'); // Use a "no operation" FieldModifier, which does not modify fields. FieldModifier fieldModifier = FieldModifiers.NOP; // Initializes a callback handler for CsvRecord objects and set the field modifier. NamedCsvRecordHandler callbackHandler = NamedCsvRecordHandler.of(c -> c. .fieldModifier(fieldModifier) ); // Use the builder to instantiate a CsvReader while passing the callback handler and the CSV file. try (CsvReader csv = builder.build(callbackHandler, file)) { for (CsvRecord record : csv) { System.out.println(record); } } ``` -------------------------------- ### Read CSV with Custom Callback Handler Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/custom-callback-handler.mdx Demonstrates reading CSV data using a custom callback handler for flexible processing. This approach is useful when built-in handlers do not meet specific data transformation or structuring needs. ```java import com.osiegmar.fastcsv.reader.CsvCallbackHandler; import com.osiegmar.fastcsv.reader.CsvReaderBuilder; import com.osiegmar.fastcsv.model.CsvColumn import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; public class ExampleCsvReaderWithCustomCallbackHandler { // Custom callback handler to process CSV data into a list of custom objects public static class CustomObject { private String name; private int age; public CustomObject(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "CustomObject{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public static class CustomObjectCallbackHandler implements CsvCallbackHandler { private final List customObjects = new ArrayList<>(); @Override public void handle(CsvColumn csvColumn) { // Assuming CSV format: name,age String name = csvColumn.getValue(0); int age = Integer.parseInt(csvColumn.getValue(1)); customObjects.add(new CustomObject(name, age)); } public List getCustomObjects() { return customObjects; } } public static void main(String[] args) { String csvData = "Alice,30\nBob,25\nCharlie,35"; StringReader reader = new StringReader(csvData); CustomObjectCallbackHandler handler = new CustomObjectCallbackHandler(); try { CsvReaderBuilder.newReader(reader) .withCallbackHandler(handler) .read(); List result = handler.getCustomObjects(); for (CustomObject obj : result) { System.out.println(obj); } } catch (IOException e) { e.printStackTrace(); } } } ``` -------------------------------- ### Add FastCSV Dependency (Maven) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Add this dependency to your pom.xml file to include FastCSV in your project. ```xml de.siegmar fastcsv ${version} ``` -------------------------------- ### Indexed Reading of a CSV File Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Use IndexedCsvReader.builder().ofCsvRecord(file) for reading CSV files with indexing capabilities. This allows efficient access to specific pages of data within the file. ```java try (IndexedCsvReader csv = IndexedCsvReader.builder().ofCsvRecord(file)) { CsvIndex index = csv.getIndex(); System.out.println("Items of last page:"); int lastPage = index.pages().size() - 1; List csvRecords = csv.readPage(lastPage); csvRecords.forEach(System.out::println); } ``` -------------------------------- ### CsvReader Custom Settings Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Configure CsvReader with custom settings such as field separator, quote character, comment strategy, and empty line handling. These options allow fine-tuning the parsing process. ```java CsvReader.builder() .fieldSeparator(';') .quoteCharacter('"') .commentStrategy(CommentStrategy.SKIP) .commentCharacter('#') .skipEmptyLines(true) .extraFieldStrategy(FieldMismatchStrategy.STRICT) .missingFieldStrategy(FieldMismatchStrategy.STRICT) .allowExtraCharsAfterClosingQuote(false) .allowUnclosedQuote(true) .detectBomHeader(false) .maxBufferSize(16777216); ``` -------------------------------- ### Read CSV Data as String Arrays with Java Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/reading-as-string-array.mdx Demonstrates reading CSV data into string arrays using the StringArrayHandler. This approach is efficient for performance-critical applications where object allocation is a concern. ```java import com.fastcsv.model.StringArrayHandler; import com.fastcsv.reader.CsvReaderBuilder; import java.io.IOException; import java.io.StringReader; import java.util.List; public class ExampleCsvReaderWithStringArrayAccess { public static void main(String[] args) throws IOException { String csvData = "header1,header2,header3\nvalue1,value2,value3\nvalue4,value5,value6"; StringReader reader = new StringReader(csvData); List records = CsvReaderBuilder.newReader(new StringArrayHandler()) .build(reader) .readAll(); // Process the records (each record is a String array) for (String[] record : records) { for (String field : record) { System.out.print(field + " "); } System.out.println(); } } } ``` -------------------------------- ### CSV File with Complex Comments Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/handle-comments.mdx Demonstrates a more complex CSV file with comments, including a '#' character within a quoted field and a multi-line field containing a comment. ```plaintext #This is a comment field 1,"field 2 with a # character","field 3 #This is not a comment, but part of the third field that spans multiple lines" ``` -------------------------------- ### Skip Non-CSV Lines with skipLines(int) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/skip-non-csv-head.mdx Use skipLines(int lineCount) to skip a predetermined number of lines at the beginning of a file, regardless of their content. This is useful when you know exactly how many non-CSV lines precede your data. ```java try (Reader reader = Files.newBufferedReader(Paths.get("example.csv"))) { CSVReader csvReader = CSVReader.builder() .skipLines(3) .build(reader); String[] line; while ((line = csvReader.read()) != null) { System.out.println(Arrays.toString(line)); } } catch (IOException e) { e.printStackTrace(); } ``` -------------------------------- ### Write CSV with CsvWriter (Basic) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/architecture.md Basic usage of CsvWriter for writing records to a CSV file. Uses try-with-resources for automatic file closing. ```java try (CsvWriter csv = CsvWriter.builder().build(file)) { csv.writeRecord("field 1", "field 2"); } ``` -------------------------------- ### Indexed CSV Reading with Pagination Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/indexed-read.mdx Index a CSV file with a specified page size and read a specific page. The index is built in the background and can be accessed to find the total number of pages. ```java import java.io.File; import java.util.List; import org.fastcsv.api.CsvRecord; import org.fastcsv.api.IndexedCsvReader; public class ExampleIndexedCsvReader { public static void main(String[] args) throws Exception { File file = new File("src/test/resources/users.csv"); // Index the CSV file with up to 5 records per page IndexedCsvReader csv = IndexedCsvReader.builder() .pageSize(5) .ofCsvRecord(file); try (csv) { // Find the last page in the index int lastPage = csv.getIndex().pages().size() - 1; // Output the last page List lastPageRecords = csv.readPage(lastPage); lastPageRecords.forEach(System.out::println); } } } ``` -------------------------------- ### Read CSV with Faulty Data in Java Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/reading-ambiguous-data.mdx Demonstrates reading a CSV file containing empty lines, empty fields, and records with missing or extra fields using FastCSV's robust parsing capabilities. ```java import com.osiegmar.fastcsv.reader.CsvReader; import com.osiegmar.fastcsv.model.CsvRow; import java.io.IOException; import java.io.StringReader; import java.util.List; public class ExampleCsvReaderWithFaultyData { public static void main(String[] args) throws IOException { String csvData = "header1,header2,header3\n" + "value1,value2,value3\n" + "\n" + "value4,,value6\n" + "value7,value8\n" + "value9,value10,value11,value12\n"; CsvReader csvReader = CsvReader.builder().build(); List rows = csvReader.read(new StringReader(csvData)); System.out.println("Headers: " + rows.get(0).getHeaders()); for (int i = 1; i < rows.size(); i++) { CsvRow row = rows.get(i); System.out.println("Row " + i + ": " + row.getValues()); System.out.println(" Value 1: " + row.get("header1")); System.out.println(" Value 2: " + row.get("header2")); System.out.println(" Value 3: " + row.get("header3")); } } } ``` -------------------------------- ### Iterative Writing of a CSV File Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Use CsvWriter.builder().build(file) within a try-with-resources statement to write CSV data to a file. Ensure the file path is correctly provided. ```java try (CsvWriter csv = CsvWriter.builder().build(file)) { csv .writeRecord("header 1", "header 2") .writeRecord("value 1", "value 2"); } ``` -------------------------------- ### Iterative Reading of CSV Data from a String Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Use CsvReader.builder().ofCsvRecord() to read CSV data directly from a string. This is useful for testing or small datasets. ```java CsvReader.builder().ofCsvRecord("foo1,bar1\nfoo2,bar2") .forEach(System.out::println); ``` -------------------------------- ### Skip Non-CSV Lines with skipLines(Predicate, int) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/skip-non-csv-head.mdx Use skipLines(Predicate predicate, int maxLines) to skip lines until a specific condition is met, such as finding the header row. The skipping stops after maxLines if the condition is not met, preventing infinite loops on malformed files. ```java try (Reader reader = Files.newBufferedReader(Paths.get("example.csv"))) { CSVReader csvReader = CSVReader.builder() .skipLines(line -> line.startsWith("header"), 5) .build(reader); String[] line; while ((line = csvReader.read()) != null) { System.out.println(Arrays.toString(line)); } } catch (IOException e) { e.printStackTrace(); } ``` -------------------------------- ### Iterative Reading of CSV Data with a Custom Header Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Use NamedCsvRecordHandler.builder() to define a custom header before building the CsvReader. This allows specifying headers that may not be present in the first row of the CSV data. ```java NamedCsvRecordHandler callbackHandler = NamedCsvRecordHandler.builder() .header("header 1", "header 2") .build(); CsvReader.builder().build(callbackHandler, "field 1,field 2") .forEach(rec -> System.out.println(rec.getField("header 2"))); ``` -------------------------------- ### Iterative Reading of CSV Data with a Header Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Use CsvReader.builder().ofNamedCsvRecord() to read CSV data where the first row is treated as a header. Access fields by their header name. ```java CsvReader.builder().ofNamedCsvRecord("header 1,header 2\nfield 1,field 2") .forEach(rec -> System.out.println(rec.getField("header 2"))); ``` -------------------------------- ### Write Basic CSV Records Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/quickstart.mdx Use CsvWriter to write basic CSV records to a file. Ensure the file path is correctly specified. ```java Path file = Path.of("output.csv"); try (CsvWriter csv = CsvWriter.builder().build(file)) { csv .writeRecord("header 1", "header 2") .writeRecord("value 1", "value 2"); } ``` -------------------------------- ### Quote in Data Fields Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Demonstrates how a double quote character within a data field is handled. ```text ^___"___$^___ ``` -------------------------------- ### Read CSV with Special Quoted Field Handling Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/quote-strategies.mdx Illustrates how to implement custom handling for quoted fields when reading CSV files, which is not supported out-of-the-box by FastCSV. This requires a custom callback handler to process fields enclosed in quotes. ```java import de.siegmar.fastcsv.reader.*; import java.io.*; import java.util.Arrays; public class ExampleCsvReaderWithSpecialQuotedFieldHandling { public static void main(String[] args) throws IOException { String csvData = "field 1, \"quoted field 2\",field 3\n"; // Custom handler to detect and process quoted fields QuotableFieldHandler handler = new QuotableFieldHandler() { @Override public void handleField(QuotableField field) { System.out.println("Field: " + field.getValue() + ", Quoted: " + field.isQuoted()); } }; CsvReader.builder() .quotableFieldHandler(handler) .build(new StringReader(csvData)) .forEach(System.out::println); } } ``` -------------------------------- ### CSV with Varying Field Counts Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Demonstrates a CSV snippet with inconsistent field counts across records. FastCSV's default behavior is to throw a CsvParseException for such cases, but this can be configured. ```csv header_a,header_bCRLF value_a_1CRLF value_a_2,value_b_2,value_c_2CRLF ``` -------------------------------- ### Detect BOM Header When Reading CSV Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Enable BOM header detection when reading CSV files using `CsvReaderBuilder.detectBomHeader(true)`. ```java CsvReaderBuilder.detectBomHeader(true) ``` -------------------------------- ### Use REQUIRED Quote Strategy Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md To explicitly define that quoting only happens if required, use the `QuoteStrategies.REQUIRED` constant with the `quoteStrategy` method in `CsvWriterBuilder`. Passing `null` is no longer accepted. ```java // Example demonstrating quote strategy configuration (not a full runnable example) // CsvWriterBuilder.quoteStrategy(QuoteStrategies.REQUIRED); ``` -------------------------------- ### Handling Duplicate Header Names Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Illustrates a CSV with duplicate header names. FastCSV's NamedCsvRecordHandlerBuilder can be configured to allow or disallow duplicate headers. ```csv header_a,header_a value_1,value_2 ``` -------------------------------- ### Read CSV from Classpath Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/read-from-classpath.mdx Use `InputStreamReader` to read a CSV file located on the classpath. Ensure the file is accessible via the classloader. ```java import com.github.lwhite1.tablesaw.api.Table; import com.github.lwhite1.tablesaw.csv.CsvReader; import java.io.InputStream; import java.io.InputStreamReader; public class ExampleCsvReaderWithClasspathInput { public static void main(String[] args) throws Exception { // Get an InputStream for the CSV file from the classpath try (InputStream inputStream = ExampleCsvReaderWithClasspathInput.class.getClassLoader().getResourceAsStream("data.csv")) { if (inputStream == null) { throw new IllegalArgumentException("Resource not found: data.csv"); } // Wrap the InputStream in an InputStreamReader try (InputStreamReader reader = new InputStreamReader(inputStream)) { // Use CsvReader to read the CSV data Table table = CsvReader.read(reader); System.out.println(table.print()); } } } } ``` -------------------------------- ### CsvWriter Custom Settings Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Configure CsvWriter with custom settings such as field separator, quote character, quote strategy, and line delimiter. These options allow fine-tuning the CSV output format. ```java CsvWriter.builder() .fieldSeparator(',') .quoteCharacter('"') .quoteStrategy(QuoteStrategies.ALWAYS) .commentCharacter('#') .lineDelimiter(LineDelimiter.LF); ``` -------------------------------- ### Mixed Newline Characters Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Illustrates the scanner's ability to handle different types of newline characters within the same input. ```text ^___ ^___ ^___ ^___ ``` -------------------------------- ### Escaped Quotes Source: https://github.com/osiegmar/fastcsv/blob/main/lib/src/intTest/resources/scanner.txt Shows how escaped double quotes (represented as two double quotes) within a quoted field are interpreted. ```text ^"_""_"$"___ ``` -------------------------------- ### Read CSV with BOM Header Detection Enabled Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/byte-order-mark.mdx Enable BOM header detection when building a CSV reader to automatically identify the file's Unicode encoding. This is useful for files created by applications like Microsoft Excel that may include a BOM. ```java import de.siegmar.fastcsv.reader.CsvReader; import de.siegmar.fastcsv.writer.CsvWriter; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.nio.charset.StandardCharsets; public class ExampleCsvReaderWithBomHeader { public static void main(String[] args) throws IOException { // Example CSV content with UTF-8 BOM String csvContentWithBom = "\uFEFF" + // UTF-8 BOM "header1,header2\n" + "value1,value2\n"; // Create a StringReader with the CSV content StringReader reader = new StringReader(csvContentWithBom); // Build CsvReader with BOM detection enabled CsvReader csvReader = CsvReader.builder() .detectBomHeader(true) // Enable BOM detection .build(reader); // Read the CSV data csvReader.forEach(row -> { for (String field : row) { System.out.print(field + " "); } System.out.println(); }); // Close the reader csvReader.close(); } } ``` -------------------------------- ### ABNF Grammar (With Comments) Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md This ABNF grammar defines the structure of CSV files when comment handling is enabled in FastCSV. ```ABNF file = *((comment / record) linebreak) comment = HASH *comment-data record = first-field *(COMMA field) linebreak = CR / LF / CRLF first-field = (escaped / first-non-escaped) field = (escaped / non-escaped) escaped = DQUOTE *(data-with-hash / COMMA / CR / LF / 2DQUOTE) DQUOTE first-non-escaped = [data *data-with-hash] non-escaped = *data-with-hash comment-data = %x00-09 / %x0B-0C / %x0E-7F / UTF8-data ; all characters except LF, CR data = %x00-09 / %x0B-0C / %x0E-21 / %x24-2B / %x2D-7F / UTF8-data ; all characters except LF, CR, DQUOTE, HASH and COMMA data-with-hash = data / HASH HASH = %x23 COMMA = %x2C CR = %x0D ; as per section B.1 of [RFC5234] CRLF = CR LF ; as per section B.1 of [RFC5234] DQUOTE = %x22 ; as per section B.1 of [RFC5234] LF = %x0A ; as per section B.1 of [RFC5234] UTF8-data = UTF8-2 / UTF8-3 / UTF8-4 ; as per section 4 of [RFC3629] ``` -------------------------------- ### Configure Comment Character Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/architecture/interpretation.md Both `CsvReaderBuilder` and `CsvWriterBuilder` allow configuring the comment character using `commentCharacter(char)`. The default is '#'. ```java commentCharacter('#') ``` -------------------------------- ### Iterative Writing of Data to a Writer Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/basic.md Use CsvWriter.builder().build(sw) to write CSV data to a StringWriter. This is useful for generating CSV content in memory. ```java var sw = new StringWriter(); CsvWriter.builder().build(sw) .writeRecord("header 1", "header 2") .writeRecord("value 1", "value 2"); System.out.println(sw); ``` -------------------------------- ### Interpreting Empty Fields as Null with FieldModifier Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/Examples/reading-null.mdx Use a custom FieldModifier to interpret unquoted empty fields as null values. This approach is useful for database imports/exports where distinguishing between null and empty is crucial. Ensure the FieldModifier correctly handles the special marker string for null. ```java import com.fastcsv.model.CSVRecord; import com.fastcsv.writer.FieldModifier; public class ExampleNamedCsvReaderWithNullFields { public static void main(String[] args) throws Exception { // Define a marker for null values final String NULL_MARKER = "__NULL__"; // Create a custom FieldModifier that replaces empty fields with the null marker FieldModifier nullFieldModifier = (field, record, index) -> { if (field.isEmpty() && !record.isQuoted(index)) { return NULL_MARKER; } return field; }; // Create a CSV reader with the custom FieldModifier try (var reader = new com.fastcsv.reader.NamedCsvReader( "name,age,city\nAlice,30,New York\nBob,,London\nCharlie,25,", nullFieldModifier )) { // Read records and process them for (CSVRecord record : reader) { String name = record.get("name"); String age = record.get("age"); String city = record.get("city"); // Check for the null marker and treat it as null Object actualAge = age.equals(NULL_MARKER) ? null : age; Object actualCity = city.equals(NULL_MARKER) ? null : city; System.out.println("Name: " + name + ", Age: " + actualAge + ", City: " + actualCity); } } } } ``` -------------------------------- ### Allow Duplicate Header Fields in NamedCsvRecordHandler Source: https://github.com/osiegmar/fastcsv/blob/main/docs/src/content/docs/guides/upgrading.md To allow duplicate header fields, call `allowDuplicateHeaderFields(true)` on the `NamedCsvRecordHandlerBuilder`. This changes the default behavior of FastCSV 4.x which rejects duplicate headers. ```java var rh = NamedCsvRecordHandler.of(c -> c.allowDuplicateHeaderFields(true)); try (CsvReader csv = CsvReader.builder().build(rh, csvFile)) { // ... } ```