package com.kgc.myread; import java.io.RandomAccessFile; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class myReader01 { private String filePath; public myReader01(String fs){ this.filePath = fs; } //记录断点的位置 private List<Long> points=new ArrayList<>(); //获取分片数 public int paetition(){ return points.size()-1; } /* * 1先找到理论分片的大小 * 2根据理论分片的位置向后搜索回车符号 * 3把找的回车点+1(代表下一行的开头) 存放到集合中 * 分片方法 * @param part 分片数 * */ public void inputSplit(int part) throws Exception { //记录文件当前读取位置 long pos=0L; //将一个节点存放到集合中 points.add(pos); //读取文件 并获得文件长度 以及每段理论长度 RandomAccessFile raf = new RandomAccessFile(filePath, "r"); long len = raf.length(); long reclen = raf.length() / part; //循环每段 并根据分段点的情况 向后搜索\n for (int i = 0; i < part; i++) { //防止用户的分段的长度达到或超过文件结尾 就把文件长度作为最后一个点存放到集合 if (pos + reclen >= len - 1) { //最后一段长度以及不足理论长度的情况 if (pos != len - 1) { points.add(len); } break; } //处理其他片 //把指针移动到新的位置上 pos += reclen; //跳过不需要读取的一段 raf.seek(pos); //判断此处是否有换行或者结束符 byte chr = raf.readByte(); while(chr!='\n' && pos<len-1){ pos++; chr = raf.readByte(); } //将指针移动到下一行的行首上 points.add(pos+1); } System.out.println(points); //关闭文件 raf.close(); } //读文件 /* * 安装用户输入的分片号进行数据读取 * @param part 分片号 * * * */ public void readFile(int part) throws Exception { //获取分片的开始和结束位置 long start = points.get(part-1); long over = points.get(part); //准备读文件 RandomAccessFile raf = new RandomAccessFile(filePath, "r"); RandomAccessFile waf = new RandomAccessFile("d:/kkk.csv", "rw"); //写文件也要指定位置 waf.seek(start); raf.seek(start); //while循环 while (start < over) { //如果开始位置小于结束位置则读一行信息 String str = new String(raf.readLine().getBytes(StandardCharsets.UTF_8)); //如果还要写 waf.writeBytes(str+"\n"); // System.out.println(Thread.currentThread().getName()+"======"+str); //将start加上读取的字符串长度再加上换行符 start += str.length() + 1; } waf.close(); raf.close(); } public static void main(String[] args) throws Exception{ //创建一个对象 myReader01 mr = new myReader01("d:/1.CSV"); //按需求分段 mr.inputSplit(10); //开启线程 线程数由集合中的数据的数量-1 设置 int threadNum = mr.paetition(); //开启固定线程池 ExecutorService pool = Executors.newFixedThreadPool(threadNum); //开启线程 for (int i = 0; i < threadNum; i++) { //获取每个线程的片号 final int part=i+1; pool.execute(()->{ try { mr.readFile(part); } catch (Exception e) { throw new RuntimeException(e); } }); } //关闭线程池 pool.shutdown(); } }
package com.kgc.myread; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class myWriter { public static void main(String[] args) throws Exception { // RandomAccessFile raf = new RandomAccessFile("d:/eee.txt", "rw"); // raf.seek(100); // raf.writeUTF("\n123123123\n"); // raf.close(); // // RandomAccessFile raf1 = new RandomAccessFile("d:/eee.txt", "rw"); // raf1.seek(10); // raf1.writeUTF("\nhello,world\n"); // raf1.close(); //创建线程池 ExecutorService pool = Executors.newFixedThreadPool(32); //创建线程 for (int i = 0; i < 32; i++) { final int k=i; //创建线程 pool.execute(()->{ //创建文件 try { //创建文件 RandomAccessFile raf1 = new RandomAccessFile("d:/eee.txt", "rw"); raf1.seek(k*32); //设置指针位置 raf1.writeUTF(Thread.currentThread().getName()+"========>hello\n"); //关闭文件 raf1.close(); } catch (FileNotFoundException e) { //抛出异常 throw new RuntimeException(e); } catch (IOException e) { //抛出异常 throw new RuntimeException(e); } }); } } }