多线程处理共享文件夹中的excel文件数据

1.首先从所有文件服务器获取文件,并组成新的集合:

//clientList为文件服务器实体类集合
clientList.forEach(c -> {
            SMBClient client = new SMBClient();
            try (Connection connection = client.connect(c.getSourceIp())) {
              	//将账号和密码放入session中
                AuthenticationContext ac = new AuthenticationContext(c.getUsername(), c.getPassword().toCharArray(), "");
                Session session = connection.authenticate(ac);
                try (DiskShare share = (DiskShare) session.connectShare(c.getShareName())) {
                    //开始获取共享文件夹数据
                    List<FileIdBothDirectoryInformation> fileInformations = new ArrayList<>();
                    share.list(c.getPath(), "*.xlsx").forEach(f -> {
                        if (null != f.getLastWriteTime()){
                            FileTime lastWriteTime = f.getLastWriteTime();
                            DateTime offsetMinute = DateUtil.offsetMinute(lastWriteTime.toDate(), 5);
                            //如果最后写入时间与当前时间小于5分钟
                            if(!offsetMinute.isAfter(new DateTime())){
                                fileInformations.add(f);
                            }
                        }
                    });
                    CountDownLatch countDownLatch = cutAndResolutionList(fileInformations, share, c.getPath());
                    countDownLatch.await();
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("解析Excel任务异常",e);
                }
            }catch (IOException e) {
                e.printStackTrace();
                log.error("解析Excel任务异常",e);
            }finally {
                client.close();
            }
        });

2.根据文件大小决定划分线程数

private CountDownLatch cutAndResolutionList(List<FileIdBothDirectoryInformation> needResolutionFile, DiskShare share, String path) {
        if(CollUtil.isEmpty(needResolutionFile)) {
            return new CountDownLatch(0);
        }
        if(needResolutionFile.size() >= 3) {//文件数据大于3时,分为3个线程
            int runSize = 3;
            int remainder = needResolutionFile.size() % runSize;  //(先计算出余数)
            int number = needResolutionFile.size() / runSize;  //然后是商
            int offset = 0;//偏移量
            CountDownLatch countDownLatch = new CountDownLatch(3);
            for (int i = 0; i < runSize; i++) {
                List<FileIdBothDirectoryInformation> threadList = null;
                if (remainder > 0) {
                    threadList = needResolutionFile.subList(i * number + offset, (i + 1) * number + offset + 1);
                    remainder--;
                    offset++;
                } else {
                    threadList = needResolutionFile.subList(i * number + offset, (i + 1) * number + offset);
                }
                CsvResolver csvResolverTread = new CsvResolver(threadList, share, countDownLatch, remoteAoiService, path);
                threadPoolTaskExecutor.execute(csvResolverTread);
            }
            return countDownLatch;
        }else {//文件数量小于3时,只使用一个线程处理
            CountDownLatch countDownLatch = new CountDownLatch(1);
            ExcelResolver csvResolverTread = new ExcelResolver(needResolutionFile, share, countDownLatch, remoteAoiService, path);
            threadPoolTaskExecutor.execute(csvResolverTread);
            return countDownLatch;
        }
    }

3.通过线程解析对应的文件数据

class ExcelResolver implements Runnable {

        private final List<FileIdBothDirectoryInformation> fileInformations;
        private final DiskShare share;
        private final CountDownLatch countDownLatch;
        private final RemoteAoiServiceImpl remoteAoiService;
        private final String path;

        public ExcelResolver (List<FileIdBothDirectoryInformation> fileInformations, DiskShare share, CountDownLatch countDownLatch, RemoteAoiServiceImpl remoteAoiService, String path) {
            this.fileInformations = fileInformations;
            this.share = share;
            this.countDownLatch = countDownLatch;
            this.remoteAoiService = remoteAoiService;
            this.path = path;
        }

        @Override
        public void run() {
            try {
                for (FileIdBothDirectoryInformation f : fileInformations) {
                    String fileName = f.getFileName();
                    long startTime = System.currentTimeMillis();
                    // File 转 MultipartFile
                    MultipartFile mockMultipartFile = null;
                    com.hierynomus.smbj.share.File file1 = null;
                    try {
                        String filePath1 ="";
                        if(StrUtil.isNotEmpty(path)){
                            filePath1 = path+"\\";
                        }
                        file1 = share.openFile(filePath1+fileName, EnumSet.of(AccessMask.GENERIC_READ), null, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null);
                        mockMultipartFile = new MockMultipartFile(fileName, file1.getInputStream());
                    } catch (Exception e) {
                        log.error("文件转换出错,文件名称为:{}",fileName, e);
                        continue;
                    }
                    String machineId = "";
                    //复制一个流
                    try {
                        //根据场内设备Id找到系统内设备id  拼接表名
                        String substring = fileName.substring(0, fileName.indexOf("-"));
                        MachineInfoVo machineInfo = baseMapper.selectMachineByEncoded(substring);
                        if (ObjectUtil.isEmpty(machineInfo) || StrUtil.isEmpty(machineInfo.getMachId())) {
                            log.info("根据表名未查询到对应设备,跳过");
                            continue;
                        }
                        // step 2 拿回来Excel文件解析(具体解析内容根据实际情况处理)
                        List<CheckData> excelData = parseExcelData(mockMultipartFile);
   						
                    } catch (Exception ignored) {
                        log.error("有文件出错:" + fileName + "ignored:::" + ignored);
                    } finally {
//                         step 3 将已经解析过的文件移动到自己的服务器
//                         step 3.1 写到自己的服务器
                        FileUtil.mkdir(targetUrl + machineId + "/");
                        File targetFile = new File(targetUrl + machineId  + "/" + fileName);
                        try{
                            if (!targetFile.exists()) {
                                FileUtil.writeFromStream(file1.getInputStream(), targetFile);
                            }
                            //step 3.2 删除共享文件夹中的文件
                            String filePath1 ="";
                            if(StrUtil.isNotEmpty(path)){
                                filePath1 = path+"\\";
                            }
                            share.rm(filePath1+f.getFileName());
                        }catch (Exception e) {
                            log.error(fileName + "文件导出或删除出错,请检查:", e);
                        }
                    }
                }
            }catch (Exception e) {
               log.error("excel解析异常",e);
            }
            countDownLatch.countDown();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值