多线程文件分割与合并

文件分割

 /**
         * 拆分文件 
         * @param fileName 待拆分的完整文件名
         * @param byteSize 按多少字节大小拆分
         * @return 拆分后的文件名列表
         * @throws IOException
         */
     public List<String> splitBySize(String fileName, int byteSize){
            List<String> parts = new ArrayList<String>();
            File file = new File(fileName);
            int count = (int) Math.ceil(file.length() / (double) byteSize);
            int countLen = (count + "").length();
            ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5,
                    10, 1, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<Runnable>(count * 2));

        for (int i = 0; i < count; i++) {
            String partFileName = file.getParent() + File.separator +  file.getName() + "."
                    + FileUtils.leftPad((i + 1) + "", countLen, '0') + ".part";
            long startPos =   (long)i * (long)byteSize;
            threadPool.execute(new SplitRunnable(byteSize, startPos,partFileName, file));
            parts.add(partFileName);
        }
        threadPool.shutdown();
    //        while (!threadPool.isTerminated()){
    //            try {
    //                Thread.sleep(1000);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
    //        }

        return parts;
    }


    private class SplitRunnable implements Runnable {
        int byteSize;
        String partFileName;
        File originFile;
        long startPos;

        public SplitRunnable(int byteSize, long startPos, String partFileName,
                             File originFile) {
            this.startPos = startPos;
            this.byteSize = byteSize;
            this.partFileName = partFileName;
            this.originFile = originFile;
        }

        public void run() {
            RandomAccessFile rFile;
            OutputStream os;
            try {
                rFile = new RandomAccessFile(originFile, "r");
                byte[] b = new byte[byteSize];
                System.out.println(startPos);
                rFile.seek(startPos);// 移动指针到每“段”开头
                int s = rFile.read(b);
                os = new FileOutputStream(partFileName);
                os.write(b, 0, s);
                os.flush();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

文件合并

/**
     * 文件合并
     * @param dirPath
     * @param partFileSuffix
     * @param partFileSize
     * @param mergeFileName
     * @throws IOException
     */
    public void mergePartFiles(String dirPath, String partFileSuffix, int partFileSize, String mergeFileName) throws IOException {
        ArrayList<File> partFiles = FileUtils.getDirFiles(dirPath, partFileSuffix);
        Collections.sort(partFiles, new FileComparator());

        RandomAccessFile randomAccessFile = new RandomAccessFile(mergeFileName,
                "rw");
        randomAccessFile.setLength(partFileSize * (partFiles.size() - 1)
                + partFiles.get(partFiles.size() - 1).length());
        randomAccessFile.close();

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                5, 10, 1, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(partFiles.size() * 2));
        for (int i = 0; i < partFiles.size(); i++) {
            long startPos = (long)i * (long)partFileSize;
            threadPool.execute(new MergeRunnable(startPos, mergeFileName, partFiles.get(i)));
        }
        threadPool.shutdown();

    }


    private class MergeRunnable implements Runnable {
        long startPos;
        String mergeFileName;
        File partFile;

        public MergeRunnable(long startPos, String mergeFileName, File partFile) {
            this.startPos = startPos;
            this.mergeFileName = mergeFileName;
            this.partFile = partFile;
        }

        public void run() {
            RandomAccessFile rFile;
            try {
                rFile = new RandomAccessFile(mergeFileName, "rw");
                rFile.seek(startPos);
                FileInputStream fs = new FileInputStream(partFile);
                byte[] b = new byte[fs.available()];
                fs.read(b);
                fs.close();
                partFile.delete();  //删除
                rFile.write(b);
                rFile.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class FileComparator implements Comparator<File> {
        public int compare(File o1, File o2) {
            return o1.getName().compareToIgnoreCase(o2.getName());
        }
    }

测试代码

public static void main(String[] args) {
        FilesMerge filesMerge = new FilesMerge();
        try{
//            filesMerge.splitBySize("E:\\abc\\b.iso",1024*1024*100);
            filesMerge.mergePartFiles("E:\\abc","part",1024*1024*100,"E:\\abc\\comb.iso");
        }catch (Exception e){
            e.printStackTrace();
        }

    }
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值