diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc950259..b776605de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.7.14 (2021-10-07) +# 5.7.14 (2021-10-08) ### 🐣新特性 * 【extra 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(issue#I4B70D@Gitee) @@ -21,6 +21,7 @@ * 【core 】 增加Opt类(pr#426@Gitee) * 【core 】 Week增加of重载,支持DayOfWek(pr#1872@Github) * 【poi 】 优化read,避免多次创建CopyOptions(issue#1875@Github) +* 【core 】 优化CsvReader,实现可控遍历(pr#1873@Github) ### 🐞Bug修复 * 【http 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(pr#418@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java index f781c61e1..db8d62e4c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java @@ -258,9 +258,8 @@ public class CsvBaseReader implements Serializable { */ private void read(CsvParser csvParser, CsvRowHandler rowHandler) throws IORuntimeException { try { - CsvRow csvRow; - while ((csvRow = csvParser.nextRow()) != null) { - rowHandler.handle(csvRow); + while (csvParser.hasNext()){ + rowHandler.handle(csvParser.next()); } } finally { IoUtil.close(csvParser); @@ -274,7 +273,7 @@ public class CsvBaseReader implements Serializable { * @return CsvParser * @throws IORuntimeException IO异常 */ - private CsvParser parse(Reader reader) throws IORuntimeException { + protected CsvParser parse(Reader reader) throws IORuntimeException { return new CsvParser(reader, this.config); } //--------------------------------------------------------------------------------------------- Private method start diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java index f995c6015..507c24ecb 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java @@ -1,5 +1,6 @@ package cn.hutool.core.text.csv; +import cn.hutool.core.collection.ComputeIter; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.map.MapUtil; @@ -24,7 +25,7 @@ import java.util.Objects; * * @author Looly */ -public final class CsvParser implements Closeable, Serializable { +public final class CsvParser extends ComputeIter implements Closeable, Serializable { private static final long serialVersionUID = 1L; private static final int DEFAULT_ROW_CAPACITY = 10; @@ -98,6 +99,11 @@ public final class CsvParser implements Closeable, Serializable { return header.fields; } + @Override + protected CsvRow computeNext() { + return nextRow(); + } + /** * 读取下一行数据 * diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReader.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReader.java index fa575b637..15065cb8f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReader.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReader.java @@ -2,11 +2,17 @@ package cn.hutool.core.text.csv; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.io.IoUtil; +import java.io.Closeable; import java.io.File; +import java.io.IOException; import java.io.Reader; import java.nio.charset.Charset; import java.nio.file.Path; +import java.util.Iterator; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * CSV文件读取器,参考:FastCSV @@ -14,7 +20,7 @@ import java.nio.file.Path; * @author Looly * @since 4.0.1 */ -public class CsvReader extends CsvBaseReader { +public class CsvReader extends CsvBaseReader implements Iterable, Closeable { private static final long serialVersionUID = 1L; private final Reader reader; @@ -117,4 +123,31 @@ public class CsvReader extends CsvBaseReader { public void read(CsvRowHandler rowHandler) throws IORuntimeException { read(this.reader, rowHandler); } + + /** + * 根据Reader创建{@link Stream},以便使用stream方式读取csv行 + * + * @return {@link Stream} + * @since 5.7.14 + */ + public Stream stream() { + return StreamSupport.stream(spliterator(), false) + .onClose(() -> { + try { + close(); + } catch (final IOException e) { + throw new IORuntimeException(e); + } + }); + } + + @Override + public Iterator iterator() { + return parse(this.reader); + } + + @Override + public void close() throws IOException { + IoUtil.close(this.reader); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvUtil.java index 8b10ca02f..ea1840076 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvUtil.java @@ -1,6 +1,7 @@ package cn.hutool.core.text.csv; import java.io.File; +import java.io.Reader; import java.io.Writer; import java.nio.charset.Charset; @@ -15,7 +16,7 @@ public class CsvUtil { //----------------------------------------------------------------------------------------------------------- Reader /** - * 获取CSV读取器 + * 获取CSV读取器,调用此方法创建的Reader须自行指定读取的资源 * * @param config 配置, 允许为空. * @return {@link CsvReader} @@ -25,7 +26,7 @@ public class CsvUtil { } /** - * 获取CSV读取器 + * 获取CSV读取器,调用此方法创建的Reader须自行指定读取的资源 * * @return {@link CsvReader} */ @@ -33,6 +34,29 @@ public class CsvUtil { 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 /** diff --git a/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java b/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java index d21bf9c3b..9563ef44e 100644 --- a/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java @@ -191,4 +191,11 @@ public class CsvReaderTest { final CsvRow row = read.getRow(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); + } }