Brian's Waste of Time

Tue, 24 May 2005

Simple CSV

I've been bitten a number of times in the last several months by there not being a decent CSV library in Java. CSV is just enough of a pain to want a somewhat thought out tool (escaping, quoted fields, possibly comment rows).

So, a simple csv tool that basically mirrors the ruby CSV library ;-) It just has a reader and writer, and usage is (hopefully) dirt easy enough that the docs consist of javadocs and some sample code in test cases:

given a sample CSV file:

Brian McCallister,(302) 994-8629
Eric McCallister,(302) 994-8991
Keith McCallister,(302) 994-8761

You can chunk it up as follows:

public void testExample1() throws Exception
{
    CSVReader reader = new SimpleReader();

    URL url = this.getClass().getClassLoader().getResource("sample.csv");
    InputStream in = url.openStream();

    List items = reader.parse(in);
    String[] first = (String[]) items.get(0);
    assertEquals("Brian McCallister", first[0]);
    assertEquals("(302) 994-8629", first[1]);

    String[] second = (String[]) items.get(1);
    assertEquals("Eric McCallister", second[0]);
    assertEquals("(302) 994-8991", second[1]);

    String[] third = (String[]) items.get(2);
    assertEquals("Keith McCallister", third[0]);
    assertEquals("(302) 994-8761", third[1]);

    in.close();
}

Or you can use the callback-based streaming api (for big files, for example):

public void testExample2() throws Exception
{
    CSVReader reader = new SimpleReader();

    URL url = this.getClass().getClassLoader().getResource("sample.csv");
    InputStream in = url.openStream();

    final int[] count = {0};
    reader.parse(in, new ReaderCallback()
    {
        public void onRow(String[] fields)
        {
            count[0]++;
            switch (count[0])
            {
                case 1:
                    assertEquals("Brian McCallister", fields[0]);
                    assertEquals("(302) 994-8629", fields[1]);
                    break;
                case 2:
                    assertEquals("Eric McCallister", fields[0]);
                    assertEquals("(302) 994-8991", fields[1]);
                    break;
                case 3:
                    assertEquals("Keith McCallister", fields[0]);
                    assertEquals("(302) 994-8761", fields[1]);
                    break;
            }
        }
    });
    assertEquals(3, count[0]);
    in.close();
}

Anyway, is trivially small, but does escaping, quotes, etc correctly -- including escaping for you when you use the writer. Have fun with it! There are no dependencies beyond the JRE standard library.

9 writebacks [/src/java] permanent link