处理方式

在处理上亿数据时,需要用到jdk1.8的Stream流

我在写这一篇博客时,实际造了一个大数据量的文件去进行实际测试,每一行为两个uuid造的数据,72位的字符串,总数据量是93940251行,文件内存6.53G

遇到这种场景时,涉及到的数据量可能会更大,比如我之前做的一个项目,实际数据量9000w,文件内存20G,每一行读出来的数据位数在200位导致文件内存更大

在处理这种文件时通过stream流懒加载的方式去跑会避免jdk内存溢出的问题,同时会将文件数据读取的速度加到最快

读取文件处理速度

代码层面

private static void readText() throws Exception {
        String filePath = "/Users/**/IdeaProjects/spring-ai/src/main/resources/text.txt";
        //文件的绝对路径
        File file = new File(filePath);
        Path path = Paths.get(filePath);
        long fileSize = Files.size(path);
        //创建File文件IO流对象,读取格式为UTF-8,读取格式为GBK就自己改一下
        try ( BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(new FileInputStream(file),"UTF-8"))){
            long startTime = System.currentTimeMillis();
            Long count = 0L;
            //while死循环,不知道文件具体的行数,需要用到死循环保证文件全部读取出来
            while (true) {
                //获取stream流
                try (Stream<String> lines = bufferedReader.lines()){
                    //分页读取该文件,5000为一页
                    try (Stream<String> limit = lines.limit(5000)){
                        //将读取出来的文件转换为集合
                        List<String> collect = limit.collect(Collectors.toList());
                        //业务逻辑处理,在业务逻辑处理时单独写一个方法进行数据处理,可以考虑对其加锁一致性,加事务保证数据幂等性
 
 
                        //计数,实际代码不需要
                        count += collect.size();
                        //当实际读取数量小于5000时,则代表为最后一页,结束读取循环
                        if(collect.size() < 5000){
                            break;
                        }
                    }
                }
            }
            long endTime = System.currentTimeMillis();
            System.out.println("读取文件总花费时间:" + ((endTime - startTime)/1000) + "秒");
            System.out.println("文件总行数为:" + count);
            System.out.println("文件大小(MB): " + (fileSize / (1024 * 1024)) + " MB");
        }
 
    }

代码解析

文件在进行跑批时,可能会存在上亿的数据量,每一个文件数据量都不一定,可能第一个在1亿,第二个在1亿1000w

通过死循环去进行读,每一次循环读取5000条,第一次循环时读取文件1-5000行的数据,第二次循环时读取5000-10000行的数据,以此类推,直至读到最后一页,在读取的数据小于5000时,则代表文件的读取到了尾声

同时在每次读取完文件后直接将读取的数据开一个线程去进行处理,做到边读边处理的功能,单纯读取速度较快,9000w行,6G内存的文件读取速度在18秒

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐