11

I'm working on a csv parser, I want to read headers and the rest of the csv file separately. Here is my code to read csv.

The current code reads everything in the csv file, but I need to read headers separate. please help me regarding this.

public class csv {

private void csvRead(File file)
{
    try
    {
    BufferedReader br = new BufferedReader( new FileReader(file));
    String strLine = "";
    StringTokenizer st = null;
    File cfile=new File("csv.txt");
    BufferedWriter writer = new BufferedWriter(new FileWriter(cfile));
    int tokenNumber = 0;

    while( (strLine = br.readLine()) != null)
    {
            st = new StringTokenizer(strLine, ",");
            while(st.hasMoreTokens())
            {

                    tokenNumber++;
                    writer.write(tokenNumber+"  "+ st.nextToken());
                    writer.newLine();
            }


            tokenNumber = 0;
            writer.flush();
    }
}

    catch(Exception e)
    {
        e.getMessage();
    }
}
Chris Dargis
  • 5,891
  • 4
  • 39
  • 63
Avinash
  • 195
  • 1
  • 4
  • 13
  • 1
    If you want to separate the reading of the headers from the rest of the file, then have a method that just handles the first line, and another method that handles all other lines in the file. – Chris Dargis Jun 26 '12 at 15:59

4 Answers4

8

We have withHeader() method available in CSVFormat. If you use this option then you will be able to read the file using headers.

CSVFormat format = CSVFormat.newFormat(',').withHeader();
Map<String, Integer> headerMap = dataCSVParser.getHeaderMap(); 

will give you all headers.

public class CSVFileReaderEx {
    public static void main(String[] args){
        readFile();
    }

    public static void readFile(){
         List<Map<String, String>> csvInputList = new CopyOnWriteArrayList<>();
         List<Map<String, Integer>> headerList = new CopyOnWriteArrayList<>();

         String fileName = "C:/test.csv";
         CSVFormat format = CSVFormat.newFormat(',').withHeader();

          try (BufferedReader inputReader = new BufferedReader(new FileReader(new File(fileName)));
                  CSVParser dataCSVParser = new CSVParser(inputReader, format); ) {

             List<CSVRecord> csvRecords = dataCSVParser.getRecords();

             Map<String, Integer> headerMap = dataCSVParser.getHeaderMap();
              headerList.add(headerMap);
              headerList.forEach(System.out::println);

             for(CSVRecord record : csvRecords){
                 Map<String, String> inputMap = new LinkedHashMap<>();

                 for(Map.Entry<String, Integer> header : headerMap.entrySet()){
                     inputMap.put(header.getKey(), record.get(header.getValue()));
                 }

                 if (!inputMap.isEmpty()) {
                     csvInputList.add(inputMap);
                } 
             }

             csvInputList.forEach(System.out::println);

          } catch (Exception e) {
             System.out.println(e);
          }
    }
}
Jaumzera
  • 2,305
  • 1
  • 30
  • 44
Rajashree Gr
  • 519
  • 1
  • 9
  • 18
6

Please consider the use of Commons CSV. This library is written according RFC 4180 - Common Format and MIME Type for Comma-Separated Values (CSV) Files. What is compatible to read such lines:

"aa,a","b""bb","ccc"

And the use is quite simple, there is just 3 classes, and a small sample according documentation:

Parsing of a csv-string having tabs as separators, '"' as an optional value encapsulator, and comments starting with '#':

 CSVFormat format = new CSVFormat('\t', '"', '#');
 Reader in = new StringReader("a\tb\nc\td");
 String[][] records = new CSVParser(in, format).getRecords();

And additionally you get this parsers already available as constants:

  • DEFAULT - Standard comma separated format as defined by RFC 4180.
  • EXCEL - Excel file format (using a comma as the value delimiter).
  • MYSQL - Default MySQL format used by the SELECT INTO OUTFILE and LOAD DATA INFILE operations. TDF - Tabulation delimited format.
Community
  • 1
  • 1
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
3

Have you considered OpenCSV?

Previous question here...

CSV API for Java

Looks like you can split out the header quite easily...

String fileName = "data.csv";
CSVReader reader = new CSVReader(new FileReader(fileName ));


// if the first line is the header
String[] header = reader.readNext();

// iterate over reader.readNext until it returns null
String[] line = reader.readNext();
Community
  • 1
  • 1
David
  • 19,577
  • 28
  • 108
  • 128
0

Your code here, being

while( (strLine = br.readLine()) != null)
    {
      //reads everything in your csv
    } 

will print all of your CSV content.

For example, the following fetches your header:

Reader in = ...;
 CSVFormat.EXCEL.withHeader("Col1", "Col2", "Col3").parse(in);

As suggested, life could be easier using the predefined CSVFormat from the apache commons library. Link here (https://commons.apache.org/proper/commons-csv/user-guide.html). Cheers.

J Maine
  • 23
  • 8