java文件分片和合并 Published on Apr 24, 2023 in Java with 0 comment 分片工具类 ```java 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; // 定义解密分块大小 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 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 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()); } } ``` 分片: ```java FileSplitUtil.split(new File(srcFilePath), splitOutputPath, splitsize); ``` 合并: ```java FileSplitUtil.merge(splitDecryptFileOutputPath, mergeFileOutputPath); ``` 本文由 admin 创作,采用 知识共享署名4.0 国际许可协议进行许可。本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。