大数据文件批处理(上亿数据量)
·
处理方式
在处理上亿数据时,需要用到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秒
更多推荐



所有评论(0)