0

I want to read different CSV files which have all a fixed column number but 2 different files have 2 different column numbers. All the files have a headerline. So I first use a CSVListReader to get the header and the column numbers and then construct the cell processors and the a CSV BeanReader to map the actual lines to POJO. I tried first to make it work with passing InputStreamReaders to the superCsv readers constructors and it doesn't work. Works fine however with FileReaders or BufferedReaders. Is it a bug or it just does not make sense to use InputStremReaders in this situation?

Here is the working code example

CsvListReader listReader = null;
FileReader file = null;
BufferedReader b = null;
try {
    file = new FileReader(linkToFile);
    b = new BufferedReader(file);
    listReader = new CsvListReader(b,
            CsvPreference.STANDARD_PREFERENCE);
    csvHeader = listReader.getHeader(true);
} catch (IOException e) {
    logger.info("Did not manage to get the Csv Header", e);
    try {
        listReader.close();
        file.close();
    } catch (IOException e1) {
        logger.info("Problem trying to close the readers", e1);
        return;
    }

  }
try {
    file = new FileReader(linkToFile);
    b = new BufferedReader(file);
    beanReader = new CsvBeanReader(b,
            CsvPreference.STANDARD_PREFERENCE);
    beanReader.getHeader(false);

    extractCSV(beanReader, csvHeader);
 catch (IOException e) {
    logger.info("Did not manage to get a working CsvBeanReader.", e);
    try {
        beanReader.close();
        listReader.close();
        file.close();
    } catch (IOException e1) {
        logger.info("Problem trying to close the readers", e1);
    }
    return;
}

Thanks in advance

Yves Nicolas
  • 6,901
  • 7
  • 25
  • 40
  • You'll have to update your answer with the stacktrace - it's really hard to tell what you mean by "it doesn't work". And a few side issues: 1. you only need to close the CsvReader (it will close the underlying stream). 2. I'm not sure why you can't just use CsvBeanReader - the only thing that's different between files is the cell processors right? So you should be able to pass different processors to `beanReader.read()` depending on the header size. – James Bassett Sep 10 '13 at 11:36
  • looking at your comment on side effect, I realized I had messed up with closing when using InputStreamReaders and that was the reason why the CSVBeanReader could actually not read anything from the file. Evreything works fine now and yes you are right, the only thing changing from 2 files are the processors which are built dynamically from the result of the header read by the CSVListReader. Thanks. – Yves Nicolas Sep 11 '13 at 05:58
  • Cool. I forgot to mention that you'll want to close your readers in a `finally` block, not just when you get an exception. – James Bassett Sep 12 '13 at 01:03

1 Answers1

0

As per Hound Doc Comments, the reason of the mess up was in a bad management of closing the different readers. Below is the working code using input stream readers

   // Reading the Header. A CsvListReader object is used here as it can
    // read a variable number of columns in the first line (see
    // http://supercsv.sourceforge.net/readers.html)
    CsvListReader listReader = null;
    InputStreamReader b = null;
    try {
        b = new InputStreamReader(new BufferedInputStream(new FileInputStream(linkToFile)));
        listReader = new CsvListReader(b, CsvPreference.STANDARD_PREFERENCE);
        csvHeader = listReader.getHeader(true);
    } catch (IOException e) {
        logger.info("Did not manage to get the Csv Header", e);
    } finally {
        try {
            listReader.close();
        } catch (IOException e1) {
            logger.info("Problem trying to close the readers", e1);
            return;
        }
    }

    // Using the CSV bean reader to read the file. Now we know the number of
    // columns
    // A CsvBeanReader object is the choice to extract easier to POJO
    // structure
    CsvBeanReader beanReader = null;

    try {
        b = new InputStreamReader(new BufferedInputStream(new FileInputStream(linkToFile)));
        beanReader = new CsvBeanReader(b, CsvPreference.STANDARD_PREFERENCE);
        // beanReader starts reading from line 2 (see above)
        // it is as if we would be reading a file without a header
        beanReader.getHeader(false);

        extractCSVContacts(beanReader, csvHeader);

    } catch (IOException e) {
        logger.info("Did not manage to get a working CsvBeanReader.", e);
       return;
    }
    finally {
        try {
            beanReader.close();
        } catch (IOException e1) {
            logger.info("Problem trying to close the readers", e1);
        }
    }
Yves Nicolas
  • 6,901
  • 7
  • 25
  • 40