Search code examples
csvsupercsv

Using both CSVListReader and CSVBeanreader in superCSV


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


Solution

  • 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);
            }
        }