Jackson MappingIterator迭代CSV时位置错误求助
Jackson MappingIterator CSV 行/列位置计数错误问题排查
使用Jackson的MappingIterator迭代CSV内容时,出现位置计数错误。CSV文件使用CRLF(0D 0A)作为换行符,但迭代返回的位置信息不符合预期:
- 实际得到:第3行 / 第31列
- 预期结果:第4行 / 第1列
代码配置如下:
Schema生成代码:
private CsvSchema getCsvSchema(final Class<A> clazz) { return csvMapper.schemaFor(clazz) .withColumnSeparator(',') .withSkipFirstDataRow(true) .withoutArrayElementSeparator(); }
迭代器创建代码:
final MappingIterator<A> iterator = csvMapper.readerFor(clazz) .with(getCsvSchema(clazz)) .with(Locale.GERMANY) .readValues(fileContent);
可能原因及解决办法
1. 换行符未被正确识别
Jackson CSV解析器默认可能未将CRLF作为完整换行符处理,导致CR(0D)被当作字段内容的一部分,仅LF(0A)被视为换行触发点。这会导致下一行的起始位置被计算在上一行的末尾列,行号也未递增。
解决:启用ALLOW_CR_AS_LINE_TERMINATOR特性,让解析器支持CR或CRLF作为有效换行符:
final MappingIterator<A> iterator = csvMapper.readerFor(clazz) .with(getCsvSchema(clazz)) .with(Locale.GERMANY) .enable(CsvParser.Feature.ALLOW_CR_AS_LINE_TERMINATOR) .readValues(fileContent);
2. 文件读取时换行符被转换
如果fileContent是通过字符流(如BufferedReader、Files.readString())读取的,JVM可能会自动将CRLF转换为LF,导致Jackson无法识别原始换行结构,位置计算出现偏差。
解决:使用字节流读取文件内容,避免换行符被修改:
try (InputStream inputStream = new FileInputStream(new File("your-csv-file.csv"))) { final MappingIterator<A> iterator = csvMapper.readerFor(clazz) .with(getCsvSchema(clazz)) .with(Locale.GERMANY) .enable(CsvParser.Feature.ALLOW_CR_AS_LINE_TERMINATOR) .readValues(inputStream); // 处理迭代逻辑 } catch (IOException e) { // 异常处理 }
3. 行号计数逻辑误解
Jackson返回的行号是物理行号(包含CSV的表头行),而你预期的可能是数据行号(跳过表头后的计数)。如果是这种情况,只需将Jackson返回的行号减去1(因为withSkipFirstDataRow(true)跳过了表头行)即可得到预期的行号。
内容的提问来源于stack exchange,提问作者Shakesbeer
相关产品推荐
相关产品推荐

