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}包含数据列表和行信息
*/
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 行处理器用于一行一行的处理数据
*/
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 {
Assert.notNull(path, "path must not be null");
return read(FileUtil.getReader(path, charset));
return read(FileUtil.getReader(path, charset), true);
}
/**
* 从Reader中读取CSV数据读取后关闭Reader
*
* @param reader Reader
* @param reader Reader
* @param closeReader 是否关闭Reader
* @return {@link CsvData}包含数据列表和行信息
* @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 List<CsvRow> rows = new ArrayList<>();
read(csvParser, rows::add);
read(csvParser, closeReader, rows::add);
final List<String> header = config.headerLineNo > -1 ? csvParser.getHeader() : null;
return new CsvData(header, rows);
@ -199,16 +200,17 @@ public class CsvBaseReader implements Serializable {
* 从Reader中读取CSV数据结果为Map读取后关闭Reader<br>
* 此方法默认识别首行为标题行
*
* @param reader Reader
* @param reader Reader
* @param closeReader 是否关闭Reader
* @return {@link CsvData}包含数据列表和行信息
* @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);
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;
}
@ -216,17 +218,18 @@ public class CsvBaseReader implements Serializable {
* 从Reader中读取CSV数据并转换为Bean列表读取后关闭Reader<br>
* 此方法默认识别首行为标题行
*
* @param <T> Bean类型
* @param reader Reader
* @param clazz Bean类型
* @param <T> Bean类型
* @param reader Reader
* @param closeReader 是否关闭Reader
* @param clazz 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);
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;
}
@ -244,19 +247,20 @@ public class CsvBaseReader implements Serializable {
this.config.setContainsHeader(true);
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;
}
/**
* 从Reader中读取CSV数据读取后关闭Reader
*
* @param reader Reader
* @param rowHandler 行处理器用于一行一行的处理数据
* @param reader Reader
* @param closeReader 是否关闭Reader
* @param rowHandler 行处理器用于一行一行的处理数据
* @throws IORuntimeException IO异常
*/
public void read(final Reader reader, final SerConsumer<CsvRow> rowHandler) throws IORuntimeException {
read(parse(reader), rowHandler);
public void read(final Reader reader, final boolean closeReader, final SerConsumer<CsvRow> rowHandler) throws IORuntimeException {
read(parse(reader), closeReader, rowHandler);
}
//--------------------------------------------------------------------------------------------- Private method start
@ -264,18 +268,21 @@ public class CsvBaseReader implements Serializable {
/**
* 读取CSV数据读取后关闭Parser
*
* @param csvParser CSV解析器
* @param rowHandler 行处理器用于一行一行的处理数据
* @param csvParser CSV解析器
* @param closeParser 是否关闭解析器
* @param rowHandler 行处理器用于一行一行的处理数据
* @throws IORuntimeException IO异常
* @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 {
while (csvParser.hasNext()){
while (csvParser.hasNext()) {
rowHandler.accept(csvParser.next());
}
} finally {
IoUtil.closeQuietly(csvParser);
if (closeParser) {
IoUtil.closeQuietly(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.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){
// issue#I49M0C@Gitee
field = StrUtil.trim(field);

View File

@ -121,7 +121,7 @@ public class CsvReader extends CsvBaseReader implements Iterable<CsvRow>, Closea
* @throws IORuntimeException IO异常
*/
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
*/
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
public void readTest() {
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(1, data.getRow(0).getOriginalLineNumber());
Assertions.assertEquals("性别", data.getRow(0).get(2));
@ -31,7 +32,7 @@ public class CsvReaderTest {
public void readMapListTest() {
final CsvReader reader = CsvUtil.getReader();
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("gender"));
@ -56,7 +57,7 @@ public class CsvReaderTest {
final CsvReader reader = CsvUtil.getReader(csvReadConfig);
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("gender"));
@ -78,7 +79,7 @@ public class CsvReaderTest {
public void readBeanListTest() {
final CsvReader reader = CsvUtil.getReader();
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).getGender());
@ -130,7 +131,8 @@ public class CsvReaderTest {
@Test
public void lineNoTest() {
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("a,b,c,d", CollUtil.join(data.getRow(0), ","));
@ -147,7 +149,8 @@ public class CsvReaderTest {
public void lineLimitTest() {
// 从原始第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("1,2,3,4", CollUtil.join(data.getRow(0), ","));
@ -165,7 +168,8 @@ public class CsvReaderTest {
public void lineLimitWithHeaderTest() {
// 从原始第2行开始读取
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("q,w,e,r,我是一段\n带换行的内容",
@ -192,7 +196,8 @@ public class CsvReaderTest {
@Test
public void readDisableCommentTest() {
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);
Assertions.assertEquals("# 这是一行注释,读取时应忽略", row.get(0));
}
@ -209,7 +214,7 @@ public class CsvReaderTest {
public void issue2306Test(){
final CsvReader reader = CsvUtil.getReader(ResourceUtil.getUtf8Reader("d:/test/issue2306.csv"));
final CsvData csvData = reader.read();
for (CsvRow csvRow : csvData) {
for (final CsvRow csvRow : csvData) {
Console.log(csvRow);
}
}

View File

@ -38,7 +38,7 @@ public class CsvUtilTest {
@Test
public void readTest2() {
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("姓名", csvRow.get(1));
@ -55,7 +55,7 @@ public class CsvUtilTest {
public void readTest3() {
final CsvReader reader = CsvUtil.getReader();
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