记一次本地TXT或CSV读取入库

记一次本地TXT或CSV读取入库

** !!! 当使用分隔符时,注意内容中存在的相同分隔符的问题 **

	public class txt2DB{
    // 一个线程最大处理数据量
    private static final int THREAD_COUNT_SIZE = 5000;
	// 临时存储list最大值
    private static final int LIST_COUNT_SIZE = 50000;
    
    @Resource
    private SmsService smsService;
    
    // 获取
    public List<Sms> getTxtSms() {
        final String path = "G:\\2and4\\20220223.txt";
        FileInputStream inputStream = null;
        Scanner sc = null;
        int count = 0;
        int errCount = 0;
        int queryCount = 0;
        List<Sms> list = new ArrayList<>();
        try {
            inputStream = new FileInputStream(path);
            sc = new Scanner(inputStream, "GBK");
            //一行一行读取数据
            while (sc.hasNextLine()) {
                count ++;
                String line = sc.nextLine();
                if(count < 2) {
                    continue;
                }
                String[] split = line.split(",");
                // 根据分隔符转对象
                Sms sms = new Sms();
                sms.setAccoutId(split[0]);
                sms.setPhoneNumber(split[1]);
                if (count % LIST_COUNT_SIZE == 0) {
                    executeThreadPool(list);
                    list.clear();
                }

                list.add(sms);
            }
            if (sc.ioException() != null) {
                throw sc.ioException();
            }
            // 存储最后读取不够分批最大值的数据
            if (list.size() > 0) {
                executeThreadPool(list);
            }
        } catch (Exception exception) {
            System.out.println(exception.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (sc != null) {
                sc.close();
            }
        }
        System.out.println(list.size());
        System.err.println("数据总行:" + count);
        return list;
    }
	//  分批入库
    public void executeThreadPool(List<Sms> smsList) {

        long start = System.currentTimeMillis();

        // 线程数,以5000条数据为一个线程,总数据大小除以5000,再加1
        int round = smsList.size() / THREAD_COUNT_SIZE + 1;
        // 程序计数器
        final CountDownLatch count = new CountDownLatch(round);
        // 创建线程
        ExecutorService executor = Executors.newFixedThreadPool(round);
        // 分配数据
        for (int i = 0; i < round; i++) {
            int startLen = i * THREAD_COUNT_SIZE;
            int endLen = ((i + 1) * THREAD_COUNT_SIZE > smsList.size() ? smsList.size()
                    : (i + 1) * THREAD_COUNT_SIZE);
            final List<Sms> threadList = smsList.subList(startLen, endLen);
            int k = i + 1;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    // 接口添加数据库,或者进行其他数据操作
                    smsService.saveOrUpdateBatch(threadList);
                    System.out.println("正在处理线程【" + k + "】的数据,数据大小为:" + threadList.size());
                    // 计数器 -1(唤醒阻塞线程)
                    count.countDown();
                }
            });
        }
        try {
            // 阻塞线程(主线程等待所有子线程 一起执行业务)
            count.await();
            long end = System.currentTimeMillis();
            System.out.println(smsList.size() + " 条数据插入查询耗时:" + (end - start) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 终止线程池
            // 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。若已经关闭,则调用没有其他作用。
            executor.shutdown();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值