前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java文件分片和合并

java文件分片和合并

作者头像
用户9131103
发布2023-07-17 19:53:09
3460
发布2023-07-17 19:53:09
举报
文章被收录于专栏:工作经验工作经验

分片工具类

代码语言:javascript
复制
package com.jinw.utils.file;

import com.jinw.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 文件分片、合并工具类
 *
 * @Author 屋顶上的蜗牛·
 * @Date 2021-09-15
 */
@Slf4j
public class FileSplitUtil {
    // 定义分块大小
    private static final int E_BLOCK_SIZE = 1024 * 1024;
<!--more-->
    // 定义解密分块大小 PKCS7Padding 16
    private static final int D_BLOCK_SIZE = 1024 * 1024 + 16;

    /**
     * 默认切割大小 (单位字节)
     * 默认以5M进行切割
     */
    private static final int DEFAULT_SIZE = 1024 * 1024 * 5; // 5M

    /**
     * 子文件下标
     */
    private static final int FILE_NAME_EXT = 1000;

    /**
     * 文件结束标识
     */
    private static final int EOF = -1;

    /**
     * 分片文件组成部分
     */
    private static final String SPLIT_FILE_NAME = "-split";

    /**
     * 匹配分片文件占位符
     */
    private static final String PLACEHOLDER = "zzz";

    /**
     * 切割指定源文件,并输出到指定目录,按默认大小切割
     *
     * @param srcFile   指定要切割的源文件
     * @param outputDir 指定输出目录
     * @throws IOException 有异常时抛出,由调用者处理
     */
    public static void split(File srcFile, String outputDir) throws IOException {
        split(srcFile, outputDir, DEFAULT_SIZE);
    }

    /**
     * 文件分片
     *
     * @param srcFile   待分片的源文件
     * @param outPutDir 分片的输出目录
     * @param size      切割大小
     * @throws IOException 有异常时抛出,由调用者处理
     */
    public static void split(File srcFile, String outPutDir, int size) throws IOException {
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(srcFile));
            //拆分成每个为几kb大小的文件
            byte[] bytes = new byte[size];

            int length;
            // 子文件下标
            int filenameExt = FILE_NAME_EXT;
            while ((length = bis.read(bytes)) > EOF) {
                int ext = filenameExt++;
                try (BufferedOutputStream bos =
                             new BufferedOutputStream(new FileOutputStream(outPutDir + ext + SPLIT_FILE_NAME))) {
                    bos.write(bytes, 0, length);
                }
            }
        } finally {
            IOUtils.closeQuietly(bis);
        }

    }

    /**
     * 合并分片文件 默认将合并后的文件放在其分片文件所在目录, 可行性决定
     *
     * @param sliceDir            所有分片文件所在目录
     * @param mergeFileOutputPath 合并输出路径
     * @throws IOException 有异常时抛出,由调用者处理
     */
    public static void merge(String sliceDir, String mergeFileOutputPath) throws IOException {
        List<String> subFileNames = getSplitFileNames(sliceDir);
        if (subFileNames.size() < 1) {
            throw new ServiceException("目录下没有分片文件...");
        }
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(
                    new FileOutputStream(mergeFileOutputPath));
            for (String subFilename : subFileNames) {
                try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sliceDir + subFilename))) {
                    // 每次读取多大字节的文件
                    byte[] bytes = new byte[DEFAULT_SIZE];
                    int length;
                    while ((length = bis.read(bytes)) > EOF) {
                        bos.write(bytes, 0, length);
                    }
                    bos.flush();
                } finally {
                    File eachSubFile = new File(sliceDir + subFilename);
                    if (eachSubFile.exists() && eachSubFile.delete()) {
                        log.info("删除分片文件成功...");
                    }
                }
            }
        } finally {
            IOUtils.closeQuietly(bos);
        }

    }

    /**
     * 获取目录下的所有分片文件名
     *
     * @param sliceDir 源目录
     * @return 结果
     */
    public static List<String> getSplitFileNames(String sliceDir) {
        File file = new File(sliceDir);
        if (!file.isDirectory()) {
            throw new ServiceException("不是一个目录...");
        }

        String[] list = file.list();
        if (list == null || list.length == 0) {
            throw new ServiceException("目录下没有任何文件...");
        }

        // 这里zzz为通用占位符、匹配分片文件
        String filename = (PLACEHOLDER + SPLIT_FILE_NAME).replace(PLACEHOLDER, "\\d+");
        return Arrays.stream(list)
                .filter(s -> s.matches(filename))
                .sorted()
                .collect(Collectors.toList());
    }
}

分片:

代码语言:javascript
复制
 FileSplitUtil.split(new File(srcFilePath), splitOutputPath, splitsize);

合并:

代码语言:javascript
复制
FileSplitUtil.merge(splitDecryptFileOutputPath, mergeFileOutputPath);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023年04月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档