Class IndexedCsvReader<T>

java.lang.Object
de.siegmar.fastcsv.reader.IndexedCsvReader<T>
Type Parameters:
T - the type of the CSV record.
All Implemented Interfaces:
Closeable, AutoCloseable

public final class IndexedCsvReader<T> extends Object implements Closeable

CSV reader implementation for indexed based access.

If no prebuilt index passed in (via IndexedCsvReader.IndexedCsvReaderBuilder.index(CsvIndex)) the constructor will initiate indexing the file. This process is optimized on performance and low memory usage – no CSV data is stored in memory. The current status can be monitored via IndexedCsvReader.IndexedCsvReaderBuilder.statusListener(StatusListener).

The index itself is held in memory, though: roughly 40 bytes per CsvIndex.CsvPage, of which there is one per IndexedCsvReader.IndexedCsvReaderBuilder.pageSize(int) records. Index memory therefore scales with the record count, not with the file size.

As indexing is performed on a byte level, only UTF-8 and single-byte charsets (such as ISO-8859-1 or US-ASCII) are supported; anything else is rejected with an IllegalArgumentException. This also applies to a charset detected via a BOM header.

Other multibyte charsets cannot be indexed byte-wise, for either of two reasons. UTF-16, UTF-32 and the variable-width legacy charsets (Shift_JIS, Big5, GBK, GB18030, ISO-2022-*, …) put ASCII byte values inside the encoding of other characters, where the indexer mistakes them for structure. Others are ASCII-transparent when encoding but consume a following byte when decoding — EUC-JP decodes any byte pair starting 0xA10xFE as one character, swallowing a line feed or separator the indexer already counted. Single-byte charsets must additionally map every ASCII byte to its own character in both directions, which rules out EBCDIC and charsets that map an ASCII byte elsewhere.

For any of these, transcode the file to UTF-8 or read it with CsvReader, which is character-oriented and supports every charset.

This class is thread-safe.

Example use:

try (IndexedCsvReader<CsvRecord> csv = IndexedCsvReader.builder().ofCsvRecord(file)) {
    CsvIndex index = csv.getIndex();
    int lastPage = index.pages().size() - 1;
    List<CsvRecord> csvRecords = csv.readPage(lastPage);
}