This commit is contained in:
Looly 2023-04-11 22:33:36 +08:00
parent eac3e0ae27
commit 51dc4141d5
5 changed files with 50 additions and 38 deletions

View File

@ -129,7 +129,7 @@ public class CsvBaseReader implements Serializable {
* @return {@link CsvData}包含数据列表和行信息 * @return {@link CsvData}包含数据列表和行信息
*/ */
public CsvData readFromStr(final String csvStr) { public CsvData readFromStr(final String csvStr) {
return read(new StringReader(csvStr)); return read(new StringReader(csvStr), true);
} }
/** /**
@ -139,7 +139,7 @@ public class CsvBaseReader implements Serializable {
* @param rowHandler 行处理器用于一行一行的处理数据 * @param rowHandler 行处理器用于一行一行的处理数据
*/ */
public void readFromStr(final String csvStr, final SerConsumer<CsvRow> rowHandler) { public void readFromStr(final String csvStr, final SerConsumer<CsvRow> rowHandler) {
read(parse(new StringReader(csvStr)), rowHandler); read(parse(new StringReader(csvStr)), true, rowHandler);
} }
@ -176,20 +176,21 @@ public class CsvBaseReader implements Serializable {
*/ */
public CsvData read(final Path path, final Charset charset) throws IORuntimeException { public CsvData read(final Path path, final Charset charset) throws IORuntimeException {
Assert.notNull(path, "path must not be null"); Assert.notNull(path, "path must not be null");
return read(FileUtil.getReader(path, charset)); return read(FileUtil.getReader(path, charset), true);
} }
/** /**
* 从Reader中读取CSV数据读取后关闭Reader * 从Reader中读取CSV数据读取后关闭Reader
* *
* @param reader Reader * @param reader Reader
* @param closeReader 是否关闭Reader
* @return {@link CsvData}包含数据列表和行信息 * @return {@link CsvData}包含数据列表和行信息
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public CsvData read(final Reader reader) throws IORuntimeException { public CsvData read(final Reader reader, final boolean closeReader) throws IORuntimeException {
final CsvParser csvParser = parse(reader); final CsvParser csvParser = parse(reader);
final List<CsvRow> rows = new ArrayList<>(); final List<CsvRow> rows = new ArrayList<>();
read(csvParser, rows::add); read(csvParser, closeReader, rows::add);
final List<String> header = config.headerLineNo > -1 ? csvParser.getHeader() : null; final List<String> header = config.headerLineNo > -1 ? csvParser.getHeader() : null;
return new CsvData(header, rows); return new CsvData(header, rows);
@ -200,15 +201,16 @@ public class CsvBaseReader implements Serializable {
* 此方法默认识别首行为标题行 * 此方法默认识别首行为标题行
* *
* @param reader Reader * @param reader Reader
* @param closeReader 是否关闭Reader
* @return {@link CsvData}包含数据列表和行信息 * @return {@link CsvData}包含数据列表和行信息
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public List<Map<String, String>> readMapList(final Reader reader) throws IORuntimeException { public List<Map<String, String>> readMapList(final Reader reader, final boolean closeReader) throws IORuntimeException {
// 此方法必须包含标题 // 此方法必须包含标题
this.config.setContainsHeader(true); this.config.setContainsHeader(true);
final List<Map<String, String>> result = new ArrayList<>(); final List<Map<String, String>> result = new ArrayList<>();
read(reader, (row) -> result.add(row.getFieldMap())); read(reader, closeReader, (row) -> result.add(row.getFieldMap()));
return result; return result;
} }
@ -218,15 +220,16 @@ public class CsvBaseReader implements Serializable {
* *
* @param <T> Bean类型 * @param <T> Bean类型
* @param reader Reader * @param reader Reader
* @param closeReader 是否关闭Reader
* @param clazz Bean类型 * @param clazz Bean类型
* @return Bean列表 * @return Bean列表
*/ */
public <T> List<T> read(final Reader reader, final Class<T> clazz) { public <T> List<T> read(final Reader reader, final boolean closeReader, final Class<T> clazz) {
// 此方法必须包含标题 // 此方法必须包含标题
this.config.setContainsHeader(true); this.config.setContainsHeader(true);
final List<T> result = new ArrayList<>(); final List<T> result = new ArrayList<>();
read(reader, (row) -> result.add(row.toBean(clazz))); read(reader, closeReader, (row) -> result.add(row.toBean(clazz)));
return result; return result;
} }
@ -244,7 +247,7 @@ public class CsvBaseReader implements Serializable {
this.config.setContainsHeader(true); this.config.setContainsHeader(true);
final List<T> result = new ArrayList<>(); final List<T> result = new ArrayList<>();
read(new StringReader(csvStr), (row) -> result.add(row.toBean(clazz))); read(new StringReader(csvStr), true, (row) -> result.add(row.toBean(clazz)));
return result; return result;
} }
@ -252,11 +255,12 @@ public class CsvBaseReader implements Serializable {
* 从Reader中读取CSV数据读取后关闭Reader * 从Reader中读取CSV数据读取后关闭Reader
* *
* @param reader Reader * @param reader Reader
* @param closeReader 是否关闭Reader
* @param rowHandler 行处理器用于一行一行的处理数据 * @param rowHandler 行处理器用于一行一行的处理数据
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public void read(final Reader reader, final SerConsumer<CsvRow> rowHandler) throws IORuntimeException { public void read(final Reader reader, final boolean closeReader, final SerConsumer<CsvRow> rowHandler) throws IORuntimeException {
read(parse(reader), rowHandler); read(parse(reader), closeReader, rowHandler);
} }
//--------------------------------------------------------------------------------------------- Private method start //--------------------------------------------------------------------------------------------- Private method start
@ -265,19 +269,22 @@ public class CsvBaseReader implements Serializable {
* 读取CSV数据读取后关闭Parser * 读取CSV数据读取后关闭Parser
* *
* @param csvParser CSV解析器 * @param csvParser CSV解析器
* @param closeParser 是否关闭解析器
* @param rowHandler 行处理器用于一行一行的处理数据 * @param rowHandler 行处理器用于一行一行的处理数据
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
* @since 5.0.4 * @since 5.0.4
*/ */
private void read(final CsvParser csvParser, final SerConsumer<CsvRow> rowHandler) throws IORuntimeException { private void read(final CsvParser csvParser, final boolean closeParser, final SerConsumer<CsvRow> rowHandler) throws IORuntimeException {
try { try {
while (csvParser.hasNext()){ while (csvParser.hasNext()) {
rowHandler.accept(csvParser.next()); rowHandler.accept(csvParser.next());
} }
} finally { } finally {
if (closeParser) {
IoUtil.closeQuietly(csvParser); IoUtil.closeQuietly(csvParser);
} }
} }
}
/** /**
* 构建 {@link CsvParser} * 构建 {@link CsvParser}

View File

@ -363,7 +363,7 @@ public final class CsvParser extends ComputeIter<CsvRow> implements Closeable, S
field = StrUtil.trim(field, StrTrimer.TrimMode.SUFFIX, (c-> c == CharUtil.LF || c == CharUtil.CR)); field = StrUtil.trim(field, StrTrimer.TrimMode.SUFFIX, (c-> c == CharUtil.LF || c == CharUtil.CR));
field = StrUtil.unWrap(field, textDelimiter); field = StrUtil.unWrap(field, textDelimiter);
field = StrUtil.replace(field, "" + textDelimiter + textDelimiter, textDelimiter + ""); field = StrUtil.replace(field, String.valueOf(textDelimiter) + textDelimiter, String.valueOf(textDelimiter));
if(this.config.trimField){ if(this.config.trimField){
// issue#I49M0C@Gitee // issue#I49M0C@Gitee
field = StrUtil.trim(field); field = StrUtil.trim(field);

View File

@ -121,7 +121,7 @@ public class CsvReader extends CsvBaseReader implements Iterable<CsvRow>, Closea
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public CsvData read() throws IORuntimeException { public CsvData read() throws IORuntimeException {
return read(this.reader); return read(this.reader, false);
} }
/** /**
@ -133,7 +133,7 @@ public class CsvReader extends CsvBaseReader implements Iterable<CsvRow>, Closea
* @since 5.0.4 * @since 5.0.4
*/ */
public void read(final SerConsumer<CsvRow> rowHandler) throws IORuntimeException { public void read(final SerConsumer<CsvRow> rowHandler) throws IORuntimeException {
read(this.reader, rowHandler); read(this.reader, false, rowHandler);
} }
/** /**

View File

@ -20,7 +20,8 @@ public class CsvReaderTest {
@Test @Test
public void readTest() { public void readTest() {
final CsvReader reader = new CsvReader(); final CsvReader reader = new CsvReader();
final CsvData data = reader.read(ResourceUtil.getReader("test.csv", CharsetUtil.UTF_8)); final CsvData data = reader.read(
ResourceUtil.getReader("test.csv", CharsetUtil.UTF_8), true);
Assertions.assertEquals("sss,sss", data.getRow(0).get(0)); Assertions.assertEquals("sss,sss", data.getRow(0).get(0));
Assertions.assertEquals(1, data.getRow(0).getOriginalLineNumber()); Assertions.assertEquals(1, data.getRow(0).getOriginalLineNumber());
Assertions.assertEquals("性别", data.getRow(0).get(2)); Assertions.assertEquals("性别", data.getRow(0).get(2));
@ -31,7 +32,7 @@ public class CsvReaderTest {
public void readMapListTest() { public void readMapListTest() {
final CsvReader reader = CsvUtil.getReader(); final CsvReader reader = CsvUtil.getReader();
final List<Map<String, String>> result = reader.readMapList( final List<Map<String, String>> result = reader.readMapList(
ResourceUtil.getUtf8Reader("test_bean.csv")); ResourceUtil.getUtf8Reader("test_bean.csv"), true);
Assertions.assertEquals("张三", result.get(0).get("姓名")); Assertions.assertEquals("张三", result.get(0).get("姓名"));
Assertions.assertEquals("", result.get(0).get("gender")); Assertions.assertEquals("", result.get(0).get("gender"));
@ -56,7 +57,7 @@ public class CsvReaderTest {
final CsvReader reader = CsvUtil.getReader(csvReadConfig); final CsvReader reader = CsvUtil.getReader(csvReadConfig);
final List<Map<String, String>> result = reader.readMapList( final List<Map<String, String>> result = reader.readMapList(
ResourceUtil.getUtf8Reader("test_bean.csv")); ResourceUtil.getUtf8Reader("test_bean.csv"), true);
Assertions.assertEquals("张三", result.get(0).get("name")); Assertions.assertEquals("张三", result.get(0).get("name"));
Assertions.assertEquals("", result.get(0).get("gender")); Assertions.assertEquals("", result.get(0).get("gender"));
@ -78,7 +79,7 @@ public class CsvReaderTest {
public void readBeanListTest() { public void readBeanListTest() {
final CsvReader reader = CsvUtil.getReader(); final CsvReader reader = CsvUtil.getReader();
final List<TestBean> result = reader.read( final List<TestBean> result = reader.read(
ResourceUtil.getUtf8Reader("test_bean.csv"), TestBean.class); ResourceUtil.getUtf8Reader("test_bean.csv"), true, TestBean.class);
Assertions.assertEquals("张三", result.get(0).getName()); Assertions.assertEquals("张三", result.get(0).getName());
Assertions.assertEquals("", result.get(0).getGender()); Assertions.assertEquals("", result.get(0).getGender());
@ -130,7 +131,8 @@ public class CsvReaderTest {
@Test @Test
public void lineNoTest() { public void lineNoTest() {
final CsvReader reader = new CsvReader(); final CsvReader reader = new CsvReader();
final CsvData data = reader.read(ResourceUtil.getReader("test_lines.csv", CharsetUtil.UTF_8)); final CsvData data = reader.read(
ResourceUtil.getReader("test_lines.csv", CharsetUtil.UTF_8), true);
Assertions.assertEquals(1, data.getRow(0).getOriginalLineNumber()); Assertions.assertEquals(1, data.getRow(0).getOriginalLineNumber());
Assertions.assertEquals("a,b,c,d", CollUtil.join(data.getRow(0), ",")); Assertions.assertEquals("a,b,c,d", CollUtil.join(data.getRow(0), ","));
@ -147,7 +149,8 @@ public class CsvReaderTest {
public void lineLimitTest() { public void lineLimitTest() {
// 从原始第2行开始读取 // 从原始第2行开始读取
final CsvReader reader = new CsvReader(CsvReadConfig.defaultConfig().setBeginLineNo(2)); final CsvReader reader = new CsvReader(CsvReadConfig.defaultConfig().setBeginLineNo(2));
final CsvData data = reader.read(ResourceUtil.getReader("test_lines.csv", CharsetUtil.UTF_8)); final CsvData data = reader.read(
ResourceUtil.getUtf8Reader("test_lines.csv"), true);
Assertions.assertEquals(2, data.getRow(0).getOriginalLineNumber()); Assertions.assertEquals(2, data.getRow(0).getOriginalLineNumber());
Assertions.assertEquals("1,2,3,4", CollUtil.join(data.getRow(0), ",")); Assertions.assertEquals("1,2,3,4", CollUtil.join(data.getRow(0), ","));
@ -165,7 +168,8 @@ public class CsvReaderTest {
public void lineLimitWithHeaderTest() { public void lineLimitWithHeaderTest() {
// 从原始第2行开始读取 // 从原始第2行开始读取
final CsvReader reader = new CsvReader(CsvReadConfig.defaultConfig().setBeginLineNo(2).setContainsHeader(true)); final CsvReader reader = new CsvReader(CsvReadConfig.defaultConfig().setBeginLineNo(2).setContainsHeader(true));
final CsvData data = reader.read(ResourceUtil.getReader("test_lines.csv", CharsetUtil.UTF_8)); final CsvData data = reader.read(
ResourceUtil.getUtf8Reader("test_lines.csv"), true);
Assertions.assertEquals(4, data.getRow(0).getOriginalLineNumber()); Assertions.assertEquals(4, data.getRow(0).getOriginalLineNumber());
Assertions.assertEquals("q,w,e,r,我是一段\n带换行的内容", Assertions.assertEquals("q,w,e,r,我是一段\n带换行的内容",
@ -192,7 +196,8 @@ public class CsvReaderTest {
@Test @Test
public void readDisableCommentTest() { public void readDisableCommentTest() {
final CsvReader reader = CsvUtil.getReader(CsvReadConfig.defaultConfig().disableComment()); final CsvReader reader = CsvUtil.getReader(CsvReadConfig.defaultConfig().disableComment());
final CsvData read = reader.read(ResourceUtil.getUtf8Reader("test.csv")); final CsvData read = reader.read(
ResourceUtil.getUtf8Reader("test.csv"), true);
final CsvRow row = read.getRow(0); final CsvRow row = read.getRow(0);
Assertions.assertEquals("# 这是一行注释,读取时应忽略", row.get(0)); Assertions.assertEquals("# 这是一行注释,读取时应忽略", row.get(0));
} }
@ -209,7 +214,7 @@ public class CsvReaderTest {
public void issue2306Test(){ public void issue2306Test(){
final CsvReader reader = CsvUtil.getReader(ResourceUtil.getUtf8Reader("d:/test/issue2306.csv")); final CsvReader reader = CsvUtil.getReader(ResourceUtil.getUtf8Reader("d:/test/issue2306.csv"));
final CsvData csvData = reader.read(); final CsvData csvData = reader.read();
for (CsvRow csvRow : csvData) { for (final CsvRow csvRow : csvData) {
Console.log(csvRow); Console.log(csvRow);
} }
} }

View File

@ -38,7 +38,7 @@ public class CsvUtilTest {
@Test @Test
public void readTest2() { public void readTest2() {
final CsvReader reader = CsvUtil.getReader(); final CsvReader reader = CsvUtil.getReader();
reader.read(FileUtil.getUtf8Reader("test.csv"), (csvRow)-> { reader.read(FileUtil.getUtf8Reader("test.csv"), true, (csvRow)-> {
// 只有一行所以直接判断 // 只有一行所以直接判断
Assertions.assertEquals("sss,sss", csvRow.get(0)); Assertions.assertEquals("sss,sss", csvRow.get(0));
Assertions.assertEquals("姓名", csvRow.get(1)); Assertions.assertEquals("姓名", csvRow.get(1));
@ -55,7 +55,7 @@ public class CsvUtilTest {
public void readTest3() { public void readTest3() {
final CsvReader reader = CsvUtil.getReader(); final CsvReader reader = CsvUtil.getReader();
final String path = FileUtil.isWindows() ? "d:/test/test.csv" : "~/test/test.csv"; final String path = FileUtil.isWindows() ? "d:/test/test.csv" : "~/test/test.csv";
reader.read(FileUtil.getUtf8Reader(path), Console::log); reader.read(FileUtil.getUtf8Reader(path), true, Console::log);
} }
@Test @Test