~/home of geeks

LineSkippingReader

· 227 Wörter · 2 Minute(n) Lesedauer

Dieser Artikel ist Teil der Artikel-Serie "kurz notiert".

Kürzlich wollte ich eine CSV-Datei einlesen, deren erste Zeilen Metainformationen zu den Daten enthielten und nicht vom Parser eingelesen werden sollten.

Die CSV-API meiner Wahl war Super-CSV, da sie im Gegensatz zur commons-csv modularer und flexibler angelegt ist.

Beide APIs benutzen einen Reader zum Einlesen der Daten, haben aber keine Funktion, um Zeilen zu überspringen.

Meine Datei hatte dabei das folgende Format

File:xyz.csv
Date:01.01.2017

header1;header2;header3;header4
value1;value2;value3;value4
valueA,valueB;valueC;valueD

Mit den ersten Zeilen mit Meta-Informationen konnten beide Parser nichts anfangen. Also musste ich einen Reader schreiben, der dazwischen geschaltet, die ersten n-Zeilen ignoriert.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.logging.Logger;

/**
 * A wrapping Reader to skip first lines of target reader.
 *
 * @author Serhat Cinar
 */
public class LineSkippingReader extends Reader {
    private static final Logger LOG = Logger.getLogger(LineSkippingReader.class);
    private final BufferedReader delegateReader;
    private final int linesToSkip;
    private boolean skipped = false;

    public LineSkippingReader(final Reader inReader, final int inLinesToSkip) {
        delegateReader = new BufferedReader(inReader);
        linesToSkip = inLinesToSkip;
    }

    public int read(char[] cbuf, int off, int len) throws IOException {
        checkSkipped();
        return delegateReader.read(cbuf, off, len);
    }

    public void close() throws IOException {
        delegateReader.close();
    }

    private void checkSkipped() throws IOException {
        if (!skipped) {
            skipped = true;
            int skippedLines = 0;
            String line;
            while (skippedLines++ < linesToSkip &&
                    (line = delegateReader.readLine()) != null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Skipping line {}: {}", skippedLines, line);
                }
            }
        }
    }
}