mirror of
https://github.com/apache/commons-csv.git
synced 2025-02-07 18:49:24 +00:00
Made CSVParser iterable to simplify the iteration over the records
git-svn-id: https://svn.apache.org/repos/asf/commons/sandbox/csv/trunk@1200024 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a7bd28c496
commit
045dbbbe4a
@ -20,7 +20,9 @@ package org.apache.commons.csv;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import static org.apache.commons.csv.CSVParser.Token.Type.*;
|
import static org.apache.commons.csv.CSVParser.Token.Type.*;
|
||||||
|
|
||||||
@ -33,14 +35,18 @@ import static org.apache.commons.csv.CSVParser.Token.Type.*;
|
|||||||
* <p>Parsing of a csv-string having tabs as separators,
|
* <p>Parsing of a csv-string having tabs as separators,
|
||||||
* '"' as an optional value encapsulator, and comments starting with '#':</p>
|
* '"' as an optional value encapsulator, and comments starting with '#':</p>
|
||||||
* <pre>
|
* <pre>
|
||||||
* String[][] record =
|
* CSVFormat format = new CSVFormat('\t', '"', '#');
|
||||||
* (new CSVParser(new StringReader("a\tb\nc\td"), new CSVFormat('\t','"','#'))).getAllValues();
|
* Reader in = new StringReader("a\tb\nc\td");
|
||||||
|
* String[][] records = new CSVParser(in, format).getRecords();
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>Parsing of a csv-string in Excel CSV format</p>
|
* <p>Parsing of a csv-string in Excel CSV format, using a for-each loop:</p>
|
||||||
* <pre>
|
* <pre>
|
||||||
* String[][] record =
|
* Reader in = new StringReader("a;b\nc;d");
|
||||||
* (new CSVParser(new StringReader("a;b\nc;d"), CSVFormat.EXCEL)).getAllValues();
|
* CSVParser parser = new CSVParser(in, CSVFormat.EXCEL);
|
||||||
|
* for (String[] record : parser) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@ -50,7 +56,7 @@ import static org.apache.commons.csv.CSVParser.Token.Type.*;
|
|||||||
* <p>see <a href="package-summary.html">package documentation</a>
|
* <p>see <a href="package-summary.html">package documentation</a>
|
||||||
* for more details</p>
|
* for more details</p>
|
||||||
*/
|
*/
|
||||||
public class CSVParser {
|
public class CSVParser implements Iterable<String[]> {
|
||||||
|
|
||||||
/** length of the initial token (content-)buffer */
|
/** length of the initial token (content-)buffer */
|
||||||
private static final int INITIAL_TOKEN_LENGTH = 50;
|
private static final int INITIAL_TOKEN_LENGTH = 50;
|
||||||
@ -172,7 +178,7 @@ public class CSVParser {
|
|||||||
* ('null' when end of file has been reached)
|
* ('null' when end of file has been reached)
|
||||||
* @throws IOException on parse error or input read-failure
|
* @throws IOException on parse error or input read-failure
|
||||||
*/
|
*/
|
||||||
public String[] getLine() throws IOException {
|
String[] getLine() throws IOException {
|
||||||
String[] ret = EMPTY_STRING_ARRAY;
|
String[] ret = EMPTY_STRING_ARRAY;
|
||||||
record.clear();
|
record.clear();
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -208,6 +214,49 @@ public class CSVParser {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator on the records. IOExceptions occuring
|
||||||
|
* during the iteration are wrapped in a RuntimeException.
|
||||||
|
*/
|
||||||
|
public Iterator<String[]> iterator() {
|
||||||
|
return new Iterator<String[]>() {
|
||||||
|
String[] current;
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (current == null) {
|
||||||
|
current = getNextLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return current != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] next() {
|
||||||
|
String[] next = current;
|
||||||
|
current = null;
|
||||||
|
|
||||||
|
if (next == null) {
|
||||||
|
// hasNext() wasn't called before
|
||||||
|
next = getNextLine();
|
||||||
|
if (next == null) {
|
||||||
|
throw new NoSuchElementException("No more CSV records available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] getNextLine() {
|
||||||
|
try {
|
||||||
|
return getLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() { }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current line number in the input stream.
|
* Returns the current line number in the input stream.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -20,7 +20,11 @@ package org.apache.commons.csv;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -219,7 +223,7 @@ public class CSVParserTest extends TestCase {
|
|||||||
assertTrue(parser.getLine() == null);
|
assertTrue(parser.getLine() == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetAllValues() throws IOException {
|
public void testGetRecords() throws IOException {
|
||||||
CSVParser parser = new CSVParser(new StringReader(code));
|
CSVParser parser = new CSVParser(new StringReader(code));
|
||||||
String[][] tmp = parser.getRecords();
|
String[][] tmp = parser.getRecords();
|
||||||
assertEquals(res.length, tmp.length);
|
assertEquals(res.length, tmp.length);
|
||||||
@ -518,7 +522,7 @@ public class CSVParserTest extends TestCase {
|
|||||||
public void testUnicodeEscape() throws IOException {
|
public void testUnicodeEscape() throws IOException {
|
||||||
String code = "abc,\\u0070\\u0075\\u0062\\u006C\\u0069\\u0063";
|
String code = "abc,\\u0070\\u0075\\u0062\\u006C\\u0069\\u0063";
|
||||||
CSVParser parser = new CSVParser(new StringReader(code), CSVFormat.DEFAULT.withUnicodeEscapesInterpreted(true));
|
CSVParser parser = new CSVParser(new StringReader(code), CSVFormat.DEFAULT.withUnicodeEscapesInterpreted(true));
|
||||||
String[] data = parser.getLine();
|
String[] data = parser.iterator().next();
|
||||||
assertEquals(2, data.length);
|
assertEquals(2, data.length);
|
||||||
assertEquals("abc", data[0]);
|
assertEquals("abc", data[0]);
|
||||||
assertEquals("public", data[1]);
|
assertEquals("public", data[1]);
|
||||||
@ -565,4 +569,42 @@ public class CSVParserTest extends TestCase {
|
|||||||
assertEquals(TOKEN + ";five;", parser.testNextToken());
|
assertEquals(TOKEN + ";five;", parser.testNextToken());
|
||||||
assertEquals(EOF + ";six;", parser.testNextToken());
|
assertEquals(EOF + ";six;", parser.testNextToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testForEach() {
|
||||||
|
List<String[]> records = new ArrayList<String[]>();
|
||||||
|
|
||||||
|
String code = "a,b,c\n1,2,3\nx,y,z";
|
||||||
|
Reader in = new StringReader(code);
|
||||||
|
|
||||||
|
for (String[] record : new CSVParser(in)) {
|
||||||
|
records.add(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(3, records.size());
|
||||||
|
assertTrue(Arrays.equals(new String[] {"a", "b", "c"}, records.get(0)));
|
||||||
|
assertTrue(Arrays.equals(new String[]{"1", "2", "3"}, records.get(1)));
|
||||||
|
assertTrue(Arrays.equals(new String[] {"x", "y", "z"}, records.get(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIterator() {
|
||||||
|
String code = "a,b,c\n1,2,3\nx,y,z";
|
||||||
|
Iterator<String[]> iterator = new CSVParser(new StringReader(code)).iterator();
|
||||||
|
|
||||||
|
assertTrue(iterator.hasNext());
|
||||||
|
iterator.remove();
|
||||||
|
assertTrue(Arrays.equals(new String[]{"a", "b", "c"}, iterator.next()));
|
||||||
|
assertTrue(Arrays.equals(new String[]{"1", "2", "3"}, iterator.next()));
|
||||||
|
assertTrue(iterator.hasNext());
|
||||||
|
assertTrue(iterator.hasNext());
|
||||||
|
assertTrue(iterator.hasNext());
|
||||||
|
assertTrue(Arrays.equals(new String[]{"x", "y", "z"}, iterator.next()));
|
||||||
|
assertFalse(iterator.hasNext());
|
||||||
|
|
||||||
|
try {
|
||||||
|
iterator.next();
|
||||||
|
fail("NoSuchElementException expected");
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user