Skip to content

Commit f78b5a1

Browse files
committed
Change CSVFormat#Iterable<CSVRecord> parse(final Reader in) to return a CSVParser, which is compatible since CSVParser implements Iterable<CSVRecord>. This allows a caller to end the parsing by calling CSVParser#close() or to use CSVParser in a Java 7 try-with-resources, without tracking a reader or input stream.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1508509 13f79535-47bb-0310-9956-ffa450edef68
1 parent 7af334d commit f78b5a1

5 files changed

Lines changed: 72 additions & 21 deletions

File tree

src/main/java/org/apache/commons/csv/CSVFormat.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -449,16 +449,16 @@ public boolean isQuoting() {
449449
return quoteChar != null;
450450
}
451451

452-
/**
453-
* Parses the specified content.
454-
*
455-
* @param in
456-
* the input stream
457-
* @return a stream of CSVRecord
458-
* @throws IOException
459-
* If an I/O error occurs
460-
*/
461-
public Iterable<CSVRecord> parse(final Reader in) throws IOException {
452+
/**
453+
* Parses the specified content.
454+
*
455+
* @param in
456+
* the input stream
457+
* @return a parser over a stream of {@link #CSVRecord}s.
458+
* @throws IOException
459+
* If an I/O error occurs
460+
*/
461+
public CSVParser parse(final Reader in) throws IOException {
462462
return new CSVParser(in, this);
463463
}
464464

src/main/java/org/apache/commons/csv/CSVParser.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ private void addRecordValue() {
236236

237237
/**
238238
* Closes resources.
239+
*
240+
* @throws IOException
241+
* If an I/O error occurs
239242
*/
240243
public void close() throws IOException {
241244
if (lexer != null) {
@@ -309,6 +312,9 @@ private CSVRecord getNextRecord() {
309312
}
310313

311314
public boolean hasNext() {
315+
if (isClosed()) {
316+
return false;
317+
}
312318
if (current == null) {
313319
current = getNextRecord();
314320
}
@@ -317,6 +323,9 @@ public boolean hasNext() {
317323
}
318324

319325
public CSVRecord next() {
326+
if (isClosed()) {
327+
return null;
328+
}
320329
CSVRecord next = current;
321330
current = null;
322331

@@ -337,4 +346,8 @@ public void remove() {
337346
};
338347
}
339348

349+
public boolean isClosed() {
350+
return lexer.isClosed();
351+
}
352+
340353
}

src/main/java/org/apache/commons/csv/ExtendedBufferedReader.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ final class ExtendedBufferedReader extends BufferedReader {
4141

4242
/** The count of EOLs (CR/LF/CRLF) seen so far */
4343
private long eolCounter = 0;
44+
45+
private boolean closed;
4446

4547
/**
4648
* Created extended buffered reader using default buffer-size
@@ -154,4 +156,23 @@ long getCurrentLineNumber() {
154156
}
155157
return eolCounter + 1; // Allow for counter being incremented only at EOL
156158
}
159+
160+
public boolean isClosed() {
161+
return closed;
162+
}
163+
164+
/**
165+
* Closes the stream.
166+
*
167+
* @throws IOException
168+
* If an I/O error occurs
169+
*/
170+
@Override
171+
public void close() throws IOException {
172+
// Set ivars before calling super close() in case close() throws an IOException.
173+
closed = true;
174+
lastChar = END_OF_STREAM;
175+
super.close();
176+
}
177+
157178
}

src/main/java/org/apache/commons/csv/Lexer.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ boolean readEndOfLine(int c) throws IOException {
148148

149149
abstract Token nextToken(Token reusableToken) throws IOException;
150150

151+
boolean isClosed() {
152+
return in.isClosed();
153+
}
154+
151155
/**
152156
* @return true if the given char is a whitespace character
153157
*/
@@ -197,10 +201,11 @@ private boolean isMetaChar(final int c) {
197201

198202
/**
199203
* Closes resources.
204+
*
205+
* @throws IOException
206+
* If an I/O error occurs
200207
*/
201208
public void close() throws IOException {
202-
if (in != null) {
203-
in.close();
204-
}
209+
in.close();
205210
}
206211
}

src/test/java/org/apache/commons/csv/CSVParserTest.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.util.NoSuchElementException;
4040

4141
import org.junit.Assert;
42-
4342
import org.junit.Ignore;
4443
import org.junit.Test;
4544

@@ -395,6 +394,19 @@ public void testCarriageReturnLineFeedEndings() throws IOException {
395394
assertEquals(4, records.size());
396395
}
397396

397+
@Test
398+
public void testClose() throws Exception {
399+
final Reader in = new StringReader("# comment\na,b,c\n1,2,3\nx,y,z");
400+
final CSVParser parser = CSVFormat.DEFAULT.withCommentStart('#').withHeader().parse(in);
401+
final Iterator<CSVRecord> records = parser.iterator();
402+
assertTrue(records.hasNext());
403+
parser.close();
404+
assertFalse(records.hasNext());
405+
assertNull(records.next());
406+
assertFalse(records.hasNext());
407+
assertNull(records.next());
408+
}
409+
398410
@Test
399411
public void testCarriageReturnEndings() throws IOException {
400412
final String code = "foo\rbaar,\rhello,world\r,kanu";
@@ -605,22 +617,22 @@ public void testGetHeaderMap() throws Exception {
605617

606618
@Test
607619
public void testGetLineNumberWithLF() throws Exception {
608-
validateLineNumbers(String.valueOf(LF));
620+
this.validateLineNumbers(String.valueOf(LF));
609621
}
610622

611623
@Test
612624
public void testGetLineNumberWithCRLF() throws Exception {
613-
validateLineNumbers(CRLF);
625+
this.validateLineNumbers(CRLF);
614626
}
615627

616628
@Test
617629
public void testGetLineNumberWithCR() throws Exception {
618-
validateLineNumbers(String.valueOf(CR));
630+
this.validateLineNumbers(String.valueOf(CR));
619631
}
620632

621633
@Test
622634
public void testGetRecordNumberWithLF() throws Exception {
623-
validateRecordNumbers(String.valueOf(LF));
635+
this.validateRecordNumbers(String.valueOf(LF));
624636
}
625637

626638
@Test
@@ -649,17 +661,17 @@ public void testGetRecordWithMultiiLineValues() throws Exception {
649661

650662
@Test
651663
public void testGetRecordNumberWithCRLF() throws Exception {
652-
validateRecordNumbers(CRLF);
664+
this.validateRecordNumbers(CRLF);
653665
}
654666

655667
@Test
656668
public void testGetRecordNumberWithCR() throws Exception {
657-
validateRecordNumbers(String.valueOf(CR));
669+
this.validateRecordNumbers(String.valueOf(CR));
658670
}
659671

660672
@Test(expected = IllegalArgumentException.class)
661673
public void testInvalidFormat() throws Exception {
662-
CSVFormat invalidFormat = CSVFormat.DEFAULT.withDelimiter(CR);
674+
final CSVFormat invalidFormat = CSVFormat.DEFAULT.withDelimiter(CR);
663675
new CSVParser((Reader) null, invalidFormat);
664676
}
665677

0 commit comments

Comments
 (0)