数据库读写百万数据

该博客展示了如何用Java实现文件的分片读取和写入,通过RandomAccessFile类操作文件。代码创建了一个myReader01类,能根据指定的分片数对文件进行分割,并使用多线程进行读取。myWriter类用于多线程写入文件。整个过程涉及到文件定位、分片计算、线程池管理和文件I/O操作。
摘要由CSDN通过智能技术生成
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);
                }
            });
        }


    }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kjshuan

点个赞就好啦!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值