add stream support for csv

This commit is contained in:
Looly 2021-10-08 16:57:02 +08:00
parent fc1dedb345
commit 26c4a44adc
6 changed files with 79 additions and 9 deletions

View File

@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.7.14 (2021-10-07) # 5.7.14 (2021-10-08)
### 🐣新特性 ### 🐣新特性
* 【extra 】 修复HttpCookie设置cookies的方法不符合RFC6265规范问题issue#I4B70D@Gitee * 【extra 】 修复HttpCookie设置cookies的方法不符合RFC6265规范问题issue#I4B70D@Gitee
@ -21,6 +21,7 @@
* 【core 】 增加Opt类pr#426@Gitee * 【core 】 增加Opt类pr#426@Gitee
* 【core 】 Week增加of重载支持DayOfWekpr#1872@Github * 【core 】 Week增加of重载支持DayOfWekpr#1872@Github
* 【poi 】 优化read避免多次创建CopyOptionsissue#1875@Github * 【poi 】 优化read避免多次创建CopyOptionsissue#1875@Github
* 【core 】 优化CsvReader实现可控遍历pr#1873@Github
### 🐞Bug修复 ### 🐞Bug修复
* 【http 】 修复HttpCookie设置cookies的方法不符合RFC6265规范问题pr#418@Gitee * 【http 】 修复HttpCookie设置cookies的方法不符合RFC6265规范问题pr#418@Gitee

View File

@ -258,9 +258,8 @@ public class CsvBaseReader implements Serializable {
*/ */
private void read(CsvParser csvParser, CsvRowHandler rowHandler) throws IORuntimeException { private void read(CsvParser csvParser, CsvRowHandler rowHandler) throws IORuntimeException {
try { try {
CsvRow csvRow; while (csvParser.hasNext()){
while ((csvRow = csvParser.nextRow()) != null) { rowHandler.handle(csvParser.next());
rowHandler.handle(csvRow);
} }
} finally { } finally {
IoUtil.close(csvParser); IoUtil.close(csvParser);
@ -274,7 +273,7 @@ public class CsvBaseReader implements Serializable {
* @return CsvParser * @return CsvParser
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
private CsvParser parse(Reader reader) throws IORuntimeException { protected CsvParser parse(Reader reader) throws IORuntimeException {
return new CsvParser(reader, this.config); return new CsvParser(reader, this.config);
} }
//--------------------------------------------------------------------------------------------- Private method start //--------------------------------------------------------------------------------------------- Private method start

View File

@ -1,5 +1,6 @@
package cn.hutool.core.text.csv; package cn.hutool.core.text.csv;
import cn.hutool.core.collection.ComputeIter;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
@ -24,7 +25,7 @@ import java.util.Objects;
* *
* @author Looly * @author Looly
*/ */
public final class CsvParser implements Closeable, Serializable { public final class CsvParser extends ComputeIter<CsvRow> implements Closeable, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final int DEFAULT_ROW_CAPACITY = 10; private static final int DEFAULT_ROW_CAPACITY = 10;
@ -98,6 +99,11 @@ public final class CsvParser implements Closeable, Serializable {
return header.fields; return header.fields;
} }
@Override
protected CsvRow computeNext() {
return nextRow();
}
/** /**
* 读取下一行数据 * 读取下一行数据
* *

View File

@ -2,11 +2,17 @@ package cn.hutool.core.text.csv;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Iterator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/** /**
* CSV文件读取器参考FastCSV * CSV文件读取器参考FastCSV
@ -14,7 +20,7 @@ import java.nio.file.Path;
* @author Looly * @author Looly
* @since 4.0.1 * @since 4.0.1
*/ */
public class CsvReader extends CsvBaseReader { public class CsvReader extends CsvBaseReader implements Iterable<CsvRow>, Closeable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final Reader reader; private final Reader reader;
@ -117,4 +123,31 @@ public class CsvReader extends CsvBaseReader {
public void read(CsvRowHandler rowHandler) throws IORuntimeException { public void read(CsvRowHandler rowHandler) throws IORuntimeException {
read(this.reader, rowHandler); read(this.reader, rowHandler);
} }
/**
* 根据Reader创建{@link Stream}以便使用stream方式读取csv行
*
* @return {@link Stream}
* @since 5.7.14
*/
public Stream<CsvRow> stream() {
return StreamSupport.stream(spliterator(), false)
.onClose(() -> {
try {
close();
} catch (final IOException e) {
throw new IORuntimeException(e);
}
});
}
@Override
public Iterator<CsvRow> iterator() {
return parse(this.reader);
}
@Override
public void close() throws IOException {
IoUtil.close(this.reader);
}
} }

View File

@ -1,6 +1,7 @@
package cn.hutool.core.text.csv; package cn.hutool.core.text.csv;
import java.io.File; import java.io.File;
import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -15,7 +16,7 @@ public class CsvUtil {
//----------------------------------------------------------------------------------------------------------- Reader //----------------------------------------------------------------------------------------------------------- Reader
/** /**
* 获取CSV读取器 * 获取CSV读取器调用此方法创建的Reader须自行指定读取的资源
* *
* @param config 配置, 允许为空. * @param config 配置, 允许为空.
* @return {@link CsvReader} * @return {@link CsvReader}
@ -25,7 +26,7 @@ public class CsvUtil {
} }
/** /**
* 获取CSV读取器 * 获取CSV读取器调用此方法创建的Reader须自行指定读取的资源
* *
* @return {@link CsvReader} * @return {@link CsvReader}
*/ */
@ -33,6 +34,29 @@ public class CsvUtil {
return new CsvReader(); return new CsvReader();
} }
/**
* 获取CSV读取器
*
* @param reader {@link Reader}
* @param config 配置, {@code null}表示默认配置
* @return {@link CsvReader}
* @since 5.7.14
*/
public static CsvReader getReader(Reader reader, CsvReadConfig config) {
return new CsvReader(reader, config);
}
/**
* 获取CSV读取器
*
* @param reader {@link Reader}
* @return {@link CsvReader}
* @since 5.7.14
*/
public static CsvReader getReader(Reader reader) {
return getReader(reader, null);
}
//----------------------------------------------------------------------------------------------------------- Writer //----------------------------------------------------------------------------------------------------------- Writer
/** /**

View File

@ -191,4 +191,11 @@ public class CsvReaderTest {
final CsvRow row = read.getRow(0); final CsvRow row = read.getRow(0);
Assert.assertEquals("# 这是一行注释,读取时应忽略", row.get(0)); Assert.assertEquals("# 这是一行注释,读取时应忽略", row.get(0));
} }
@Test
@Ignore
public void streamTest(){
final CsvReader reader = CsvUtil.getReader(ResourceUtil.getUtf8Reader("test_bean.csv"));
reader.stream().limit(2).forEach(Console::log);
}
} }