public static void main(String[] args) throws IOException {
File file = new File("D:/a.txt");
BufferedReader br = new BufferedReader(new FileReader("D:/a.txt"));
long len = file.length();//获得文件总长度
System.out.println(len);
//理论长度
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++;
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;
//jdk1.8提供的Lambda表达式,如果接口中只有一个方法,可以写成如下形式,()表示run方法的参数列表,{}里面是方法体内容
pool.execute(() -> {
try {
//每个线程开启读取文件
BufferedReader br1 = new BufferedReader(new FileReader("D:/a.txt"));
char[] handlerArr = new char[(int) (pos.get(flag + 1) - pos.get(flag))];
br1.skip(pos.get(flag));
//read(byte[] b)方法:从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。返回实际读取的字节数。
br1.read(handlerArr);
String str = new String(handlerArr); //以一个字符数组为参数,将字符数组转换成一个字符串
String[] infos = str.split("\\s+"); // \\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();
}
});
}
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(pos);
System.out.println(lst);
System.out.println(res);
}