Skip to content

Commit

Permalink
change convenience methods in builder and add ofNamedRecord
Browse files Browse the repository at this point in the history
  • Loading branch information
osiegmar committed Jan 5, 2024
1 parent d23d63e commit 8d2da14
Show file tree
Hide file tree
Showing 30 changed files with 449 additions and 241 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated from Java 8 to Java 11
- Updated naming (rows/lines -> records, columns -> fields, differentiate between lines and records)
- `NamedCsvReader` replaced by `CsvReader` with `CsvCallbackHandlers`
- `build` methods in `CsvReaderBuilder` with callback handlers and `ofCsvRecord` / `ofNamedCsvRecord` as convenience methods
- Rename `errorOnDifferentFieldCount()` to `ignoreDifferentFieldCount()`
- Rename `isEmpty()` to `isEmptyLine` in `CsvRecord`
- `QuoteStrategy` is now an interface – defaults are provided by `QuoteStrategies`
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,29 +88,32 @@ As one of the most popular CSV libraries for Java on GitHub, FastCSV comes with
### Iterative reading of some CSV data from a string

```java
CsvReader.builder().build("foo1,bar1\nfoo2,bar2")
CsvReader.builder().ofCsvRecord("foo1,bar1\nfoo2,bar2")
.forEach(System.out::println);
```

### Iterative reading of a CSV file

```java
try (CsvReader<CsvRecord> csv = CsvReader.builder().build(file)) {
try (CsvReader<CsvRecord> csv = CsvReader.builder().ofCsvRecord(file)) {
csv.forEach(System.out::println);
}
```

### Iterative reading of some CSV data with a header

```java
CsvReader.builder().build("header 1,header 2\nfield 1,field 2", CsvCallbackHandlers.ofNamedCsvRecord())
CsvReader.builder().ofNamedCsvRecord("header 1,header 2\nfield 1,field 2")
.forEach(rec -> System.out.println(rec.getField("header2")));
```

### Iterative reading of some CSV data with a custom header

```java
CsvReader.builder().build("field 1,field 2", CsvCallbackHandlers.ofNamedCsvRecord("header 1", "header 2"))
CsvCallbackHandler<NamedCsvRecord> callbackHandler =
CsvCallbackHandlers.ofNamedCsvRecord("header1", "header2");

CsvReader.builder().build(callbackHandler, "field 1,field 2")
.forEach(rec -> System.out.println(rec.getField("header2")));
```

Expand All @@ -133,7 +136,7 @@ CsvReader.builder()
### Indexed reading of a CSV file

```java
try (IndexedCsvReader csv = IndexedCsvReader.builder().build(file)) {
try (IndexedCsvReader<CsvRecord> csv = IndexedCsvReader.builder().ofCsvRecord(file)) {
CsvIndex index = csv.index();

System.out.println("Items of last page:");
Expand Down
15 changes: 13 additions & 2 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ see the [changelog](CHANGELOG.md).
**Reading CSV records:**

```java
try (CsvReader<CsvRecord> csv = CsvReader.builder().build(file)) {
try (CsvReader<CsvRecord> csv = CsvReader.builder().ofCsvRecord(file)) {
csv.forEach(System.out::println);
}
```
Expand All @@ -41,6 +41,7 @@ try (CsvWriter csv = CsvWriter.builder().build(file)) {
- In `CsvReaderBuilder`:
- `skipEmptyRows` is now `skipEmptyLines`
- `errorOnDifferentFieldCount` is now `ignoreDifferentFieldCount` (opposite meaning!)
- `build` methods with callback handlers and `ofCsvRecord` / `ofNamedCsvRecord` as convenience methods
- In `CsvRecord` (former `CsvRow`):
- `getOriginalLineNumber` is now `getStartingLineNumber`

Expand All @@ -50,7 +51,17 @@ A distinct `NamedCsvReader` is no longer needed as the `CsvReader` now supports
processing.

```java
CsvReader.builder().build("header 1,header 2\nfield 1,field 2", CsvCallbackHandlers.ofNamedCsvRecord())
CsvReader.builder().ofNamedCsvRecord("header 1,header 2\nfield 1,field 2")
.forEach(rec -> System.out.println(rec.getField("header2")));
```

or with a custom header:

```java
CsvCallbackHandler<NamedCsvRecord> callbackHandler =
CsvCallbackHandlers.ofNamedCsvRecord("header1", "header2");

CsvReader.builder().build(callbackHandler, "field 1,field 2")
.forEach(rec -> System.out.println(rec.getField("header2")));
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ExampleCsvReaderWithBomHeader {
public static void main(final String[] args) throws IOException {
final Path testFile = prepareTestFile();
final CsvReader.CsvReaderBuilder builder = CsvReader.builder().detectBomHeader(true);
try (Stream<CsvRecord> stream = builder.build(testFile).stream()) {
try (Stream<CsvRecord> stream = builder.ofCsvRecord(testFile).stream()) {
stream.forEach(System.out::println);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
public class ExampleCsvReaderWithClasspathInput {

public static void main(final String[] args) throws IOException {
try (CsvReader<CsvRecord> csv = CsvReader.builder().build(getReader("/example.csv"))) {
try (CsvReader<CsvRecord> csv = CsvReader.builder().ofCsvRecord(getReader("/example.csv"))) {
for (final CsvRecord csvRecord : csv) {
System.out.println(csvRecord.getFields());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ public class ExampleCsvReaderWithComments {
public static void main(final String[] args) {
System.out.println("Reading data with no special treatment for comments:");
CsvReader.builder()
.build(DATA)
.ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Reading data while skipping comments:");
CsvReader.builder()
.commentStrategy(CommentStrategy.SKIP)
.build(DATA)
.ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Reading data while reading comments:");
CsvReader.builder()
.commentStrategy(CommentStrategy.READ)
.build(DATA)
.ofCsvRecord(DATA)
.forEach(rec -> {
if (rec.isComment()) {
System.out.println("Comment: " + rec.getField(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static void main(final String[] args) {
);

System.out.println("Mapping data with simple mapper callback handler:");
for (final Person person : CsvReader.builder().build(DATA, mapper)) {
for (final Person person : CsvReader.builder().build(mapper, DATA)) {
System.out.println(person);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ public class ExampleCsvReaderWithFaultyData {
public static void main(final String[] args) {
System.out.println("Reading data with lenient (default) settings:");
CsvReader.builder()
.build(DATA)
.ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Reading data while not skipping empty lines:");
CsvReader.builder()
.skipEmptyLines(false)
.build(DATA)
.ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Reading data while not ignoring different field counts:");
try {
CsvReader.builder()
.ignoreDifferentFieldCount(false)
.build(DATA)
.ofCsvRecord(DATA)
.forEach(System.out::println);
} catch (final CsvParseException e) {
System.out.println(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public class ExampleCsvReaderWithFieldModifier {

public static void main(final String[] args) {
System.out.println("Trim fields:");
builderWithTrim().build(DATA)
builderWithTrim().ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Trim and lowercase fields:");
builderWithTrimAndLowerCase().build(DATA)
builderWithTrimAndLowerCase().ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Trim and lowercase fields of first record (by using a custom modifier):");
builderWithCustomModifier().build(DATA)
builderWithCustomModifier().ofCsvRecord(DATA)
.forEach(System.out::println);
}

Expand Down
12 changes: 6 additions & 6 deletions example/src/main/java/example/ExampleCsvReaderWithFileInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,28 @@ public static void main(final String[] args) throws IOException {
final Path tmpFile = prepareTestFile();

System.out.println("Reading data via for-each loop:");
try (CsvReader<CsvRecord> csv = CsvReader.builder().build(tmpFile)) {
try (CsvReader<CsvRecord> csv = CsvReader.builder().ofCsvRecord(tmpFile)) {
for (final CsvRecord csvRecord : csv) {
System.out.println(csvRecord.getFields());
}
}

System.out.println("Reading data via forEach lambda:");
try (CsvReader<CsvRecord> csv = CsvReader.builder().build(tmpFile)) {
try (CsvReader<CsvRecord> csv = CsvReader.builder().ofCsvRecord(tmpFile)) {
csv.forEach(System.out::println);
}

System.out.println("Reading data via stream:");
try (Stream<CsvRecord> stream = CsvReader.builder().build(tmpFile).stream()) {
try (Stream<CsvRecord> stream = CsvReader.builder().ofCsvRecord(tmpFile).stream()) {
stream
.map(rec -> rec.getField(1))
.forEach(System.out::println);
}

System.out.println("Reading data via iterator:");
try (CloseableIterator<CsvRecord> iterator = CsvReader.builder().build(tmpFile).iterator()) {
while (iterator.hasNext()) {
final CsvRecord csvRecord = iterator.next();
try (CloseableIterator<CsvRecord> it = CsvReader.builder().ofCsvRecord(tmpFile).iterator()) {
while (it.hasNext()) {
final CsvRecord csvRecord = it.next();
System.out.println(csvRecord.getFields());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static void main(final String[] args) {
CsvReader.builder()
.fieldSeparator(';')
.quoteCharacter('\'')
.build(DATA)
.ofCsvRecord(DATA)
.forEach(System.out::println);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package example;

import java.util.Iterator;

import de.siegmar.fastcsv.reader.CsvReader;
import de.siegmar.fastcsv.reader.CsvRecord;

Expand All @@ -14,22 +12,22 @@ public class ExampleCsvReaderWithStringInput {

public static void main(final String[] args) {
System.out.println("Reading data via for-each loop:");
for (final CsvRecord csvRecord : CsvReader.builder().build(DATA)) {
for (final CsvRecord csvRecord : CsvReader.builder().ofCsvRecord(DATA)) {
System.out.println(csvRecord.getFields());
}

System.out.println("Reading data via forEach lambda:");
CsvReader.builder().build(DATA)
CsvReader.builder().ofCsvRecord(DATA)
.forEach(System.out::println);

System.out.println("Reading data via stream:");
CsvReader.builder().build(DATA).stream()
CsvReader.builder().ofCsvRecord(DATA).stream()
.map(rec -> rec.getField(1))
.forEach(System.out::println);

System.out.println("Reading data via iterator:");
for (final Iterator<CsvRecord> iterator = CsvReader.builder().build(DATA).iterator(); iterator.hasNext();) {
final CsvRecord csvRecord = iterator.next();
for (final var it = CsvReader.builder().ofCsvRecord(DATA).iterator(); it.hasNext();) {
final CsvRecord csvRecord = it.next();
System.out.println(csvRecord.getFields());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.io.IOException;
import java.io.StringWriter;

import de.siegmar.fastcsv.reader.CsvCallbackHandlers;
import de.siegmar.fastcsv.reader.CsvReader;
import de.siegmar.fastcsv.reader.NamedCsvRecord;
import de.siegmar.fastcsv.writer.CsvWriter;
Expand All @@ -18,7 +17,7 @@ public class ExampleCsvWriterWithDataTransformation {
public static void main(final String[] args) throws IOException {
final StringWriter out = new StringWriter();

try (CsvReader<NamedCsvRecord> reader = CsvReader.builder().build(DATA, CsvCallbackHandlers.ofNamedCsvRecord());
try (CsvReader<NamedCsvRecord> reader = CsvReader.builder().ofNamedCsvRecord(DATA);
CsvWriter writer = CsvWriter.builder().build(out)) {

// transform firstname, initial, lastname to lastname, firstname
Expand Down
18 changes: 9 additions & 9 deletions example/src/main/java/example/ExampleIndexedCsvReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ private static Path createTmpFile() throws IOException {
private static void simple(final Path file) throws IOException {
System.out.println("# Simple read");

final IndexedCsvReader csv = IndexedCsvReader.builder()
final IndexedCsvReader<CsvRecord> csv = IndexedCsvReader.builder()
.pageSize(5)
.build(file);
.ofCsvRecord(file);

try (csv) {
final CsvIndex index = csv.index();
Expand All @@ -79,17 +79,17 @@ private static void reuseIndex(final Path file) throws IOException {

final CsvIndex csvIndex = IndexedCsvReader.builder()
.pageSize(5)
.build(file)
.ofCsvRecord(file)
.index();

System.out.printf("Indexed %,d records%n", csvIndex.recordCount());

// Store index for the given file somewhere, and use it later ...

final IndexedCsvReader csv = IndexedCsvReader.builder()
final IndexedCsvReader<CsvRecord> csv = IndexedCsvReader.builder()
.pageSize(5)
.index(csvIndex)
.build(file);
.ofCsvRecord(file);

try (csv) {
System.out.println("Show records of last page");
Expand Down Expand Up @@ -118,9 +118,9 @@ private static void statusMonitor(final Path file) throws IOException {
},
0, 250, TimeUnit.MILLISECONDS);

final IndexedCsvReader csv = IndexedCsvReader.builder()
final IndexedCsvReader<CsvRecord> csv = IndexedCsvReader.builder()
.statusListener(statusListener)
.build(file);
.ofCsvRecord(file);

try (csv) {
System.out.printf("Indexed %,d records%n", csv.index().recordCount());
Expand All @@ -130,13 +130,13 @@ private static void statusMonitor(final Path file) throws IOException {
}

private static void advancedConfiguration(final Path file) throws IOException {
final IndexedCsvReader csv = IndexedCsvReader.builder()
final IndexedCsvReader<CsvRecord> csv = IndexedCsvReader.builder()
.fieldSeparator(',')
.quoteCharacter('"')
.commentStrategy(CommentStrategy.NONE)
.commentCharacter('#')
.pageSize(5)
.build(file);
.ofCsvRecord(file);

try (csv) {
final List<CsvRecord> csvRecords = csv.readPage(2);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package example;

import de.siegmar.fastcsv.reader.CsvCallbackHandler;
import de.siegmar.fastcsv.reader.CsvCallbackHandlers;
import de.siegmar.fastcsv.reader.CsvReader;
import de.siegmar.fastcsv.reader.NamedCsvRecord;

/**
* Example for reading CSV data with a custom header.
Expand All @@ -11,7 +13,10 @@ public class ExampleNamedCsvReaderWithCustomHeader {
private static final String DATA = "value1,value2\nfoo,bar";

public static void main(final String[] args) {
CsvReader.builder().build(DATA, CsvCallbackHandlers.ofNamedCsvRecord("header1", "header2"))
final CsvCallbackHandler<NamedCsvRecord> callbackHandler =
CsvCallbackHandlers.ofNamedCsvRecord("header1", "header2");

CsvReader.builder().build(callbackHandler, DATA)
.forEach(rec -> System.out.println(rec.getField("header2")));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package example;

import de.siegmar.fastcsv.reader.CsvCallbackHandlers;
import de.siegmar.fastcsv.reader.CsvReader;

/**
Expand All @@ -12,7 +11,7 @@ public class ExampleNamedCsvReaderWithStringInput {

public static void main(final String[] args) {
System.out.println("Field 'header2' of each record:");
CsvReader.builder().build(DATA, CsvCallbackHandlers.ofNamedCsvRecord())
CsvReader.builder().ofNamedCsvRecord(DATA)
.forEach(rec -> System.out.println(rec.getField("header2")));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CsvReaderBomHeaderTest {
@ParameterizedTest
@MethodSource
void bom(final Path testFile) throws IOException {
assertThat(crb.build(testFile).stream())
assertThat(crb.ofCsvRecord(testFile).stream())
.satisfiesExactly(
c -> CsvRecordAssert.assertThat(c).fields().containsExactly("foo", "üÜß"),
c -> CsvRecordAssert.assertThat(c).fields().containsExactly("123", "456")
Expand Down
Loading

0 comments on commit 8d2da14

Please sign in to comment.