csv文件读取换行字符错乱问题


前言

从华为云oss读取csv文件时发现解析数据时与源数据条数对不上,数据解析错乱

一、问题现象

1.问题代码

URL url = new URL(req.getOssUrl());
InputStream inputStream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader, IoUtil.DEFAULT_BUFFER_SIZE);
// 源数据有502条,却解析成520条
List<JSONObject> jsonObjects = CsvUtil.getReader().read(bufferedReader, JSONObject.class);

2.问题现象

在这里插入图片描述
在这里插入图片描述
debug发现解析的数据与源数据对不上,且源数据有,字符被提前分割了(csv文件每列以,号分割)

二、问题分析

1.hutool工具是怎么解析一行的

在这里插入图片描述
在这里插入图片描述
有问题的那行数据,有\n字符,在解析时被认为这是另一行被提前分割了,def roundfun(i0,j0,n,m,num): 字符就认为是一行的数据,再以逗号分隔为每列的数据,最终看到一行的数据就是def roundfun(i0 j0 n m num这几列,显然这样解析不对
看CsvConfig源码是以,号为每个字段(列)为分割符,但是源数据里的是第一列包括了逗号被提前分割了

2.怎么解决\n符呢?

1、看hutool工具源码有设置字段分割符CsvConfig.setFieldSeparator(fieldSeparator)。但是现在的问题是怎么忽略\n这种正常换行字符和字段分割符(,号)无关,hutool工具没有对应的设置类。
2、查资料opencsv可以解决此类问题

三、解决方案(opencsv解析)

1.maven配置

<dependency>
	<groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>4.5</version>            
 </dependency>

2.代码修改

URL url = new URL(req.getOssUrl());
InputStream inputStream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader, IoUtil.DEFAULT_BUFFER_SIZE);
List<JSONObject> jsonObjects = readCsv(bufferedReader);
    /**
     * 读取csv格式文件
     * @param reader
     * @return
     */
    private List<JSONObject> readCsv(Reader reader) {
        // 忽略\n换行字符,避免同一行的数据被分割
        CSVReader csvReader = new CSVReader(reader, ',', '"', '\n');
        Iterator<String[]> iterator = csvReader.iterator();
        boolean head = true;
        // 表头
        List<String> headList = null;
        List<JSONObject> jsonObjects = Lists.newArrayList();
        while (iterator.hasNext()) {
            String[] next = iterator.next();
            if (head) {
                head = false;
                headList = Lists.newArrayList(next);
                continue;
            }
            JSONObject jsonObject = convertJson(next, headList);
            jsonObjects.add(jsonObject);
        }
        try {
            // 要把对应流关闭
            csvReader.close();
        } catch (IOException e) {
            log.error("read bi callback csv failed!", e);
        }
        return jsonObjects;
    }

在这里插入图片描述
看CSVReader默认是忽略\字符,但我们需要忽略\n字符,因此定义为CSVReader csvReader = new CSVReader(reader, ‘,’, ‘"’, ‘\n’);

总结

1、csv文件有\n换行字符解析可能会错乱,可通过opencsv包CSVReader csvReader = new CSVReader(reader, ‘,’, ‘"’, ‘\n’);解决,也可自行处理
2、测试文件:https://csdn-bi-data.obs.cn-north-4.myhuaweicloud.com:443/xongkoro/download/tmp_odps_download_41291366e907423c9733737533345ffa/part-00000-589afb42-3310-40b3-9dad-1f11e317db01-c000.csv?AccessKeyId=IR5RUNOTFAJTRVVHR9KN&Expires=1691549909&Signature=XR7oeAbTem22yHjoqvWZUIPhOJ8%3D

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值