package org.example;
import java.io.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class App2 {
public static void main(String[] args) throws IOException {
File file = new File("d:/data1.txt");//文件流
// System.out.println(file.length());
BufferedReader br = new BufferedReader(new FileReader("d:/data1.txt"));//读文件
long len = file.length();//获得文件总长度
long duan = len / 5;//根据需要将文件分段
List<Long> pos = new ArrayList<>();// 准备坐标集合
pos.add(0L);//首个坐标设置为0 起始位置 线程读取文件的起始位置 放到集合中
long currPos = 0;//当前坐标位置
while ((currPos + duan) < len) {//游标不断前移 但是不能超过文件总长度
currPos += duan;//游标前移(理论值)
br.skip(duan);//让读文件跳过游标位置
int chr = br.read();//读取游标后的一个字符串
currPos++;
//空格是32;回车是13;
while (chr != 32 && chr != 13 && chr != -1) {//判定字符是否是回车、空格、结尾3个字符之一 不是就继续
chr = br.read();//再读一次字节
currPos++;//每次字节数++
// br.skip(currPos);//接着跳过游标
}
//把当前位置存放到坐标数组中
pos.add(currPos);//每段的终 下一段始
}
pos.add(len);//把文件总字数存放到集合中 最后一段的终
//准备一个List<map>集合
List<Map<String,Integer>>lst=new ArrayList<>();
for (int i = 0; i <5 ; i++) {
lst.add(new HashMap<>());
}
//开启线程进行读取
ExecutorService pool = Executors.newFixedThreadPool(5);
for (int i = 0; i <5; i++) {
final int flag=i;//flag线程的下标
pool.execute(()->{//参数列表 前提是接口里就一个方法
try {
//每个线程开启读取文件
BufferedReader br1 = new BufferedReader(new FileReader("d:/data1.txt"));
//下一段的开头-上一段开头 =字符长度
char[]handlerArr=new char[(int)(pos.get(flag+1)-pos.get(flag))];
br1.skip(pos.get(flag));
//读整段
br1.read(handlerArr);
//把读出来的内容转为字符串
String str =new String(handlerArr);
//字符串用空格分割
String[]infos=str.split("\\s+");
//将每个单词存放到线程对应的那个集合中
for (String word:infos) {
if (lst.get(flag).containsKey(word)){
lst.get(flag).put(word.trim(),lst.get(flag).get(word)+1);
}else {
lst.get(flag).put(word.trim(),1);
}
}
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(Thread.currentThread().getName());
});
}
pool.shutdown();
//如果线程中没有激活的线程
while (!pool.isTerminated());
//蒋所集合中的数据合并
Map<String,Integer>res=new HashMap<>();
for (Map<String,Integer>sub:lst){
for (String key:sub.keySet()){
if (res.containsKey(key.trim())){
res.put(key.trim(),res.get(key)+sub.get(key));
}else {
res.put(key.trim(),sub.get(key));
}
}
}
System.out.println(res);
}
}
wordCount线程池详解(统计大文件单词个数)
最新推荐文章于 2024-03-24 16:37:40 发布