测试大文件分块和合并

发布时间 2023-07-11 11:42:27作者: duanthirty

文件分块的流程

  1. 获取源文件长度
  2. 根据设定的分块文件大小,计算出块数(向上取整,例如33.4M的文件,块大小为1M,则需要34块)
  3. 从源文件读取数据,并依次向每一个块文件写数据

文件分块测试代码如下

/**
    * 分块测试
    */
   @Test
   void testChunk() throws IOException {
       //源文件
       File file = new File("C:\\Users\\thirty\\Videos\\Captures\\1.mp4");
       //分块存储路径
       String chunkFilePath = "D:\\video\\chunk\\";
       //分块文件的大小
       int chunkSize = 1024 * 1024;
       //分块文件个数
       int chunkNum = Math.toIntExact(file.length() / chunkSize);
       if (file.length() % chunkSize != 0) {
           chunkNum += 1;
       }
       // 缓冲区大小
       byte[] bytes = new byte[1024];
       // 使用RandomAccessFile访问文件
       RandomAccessFile file_r = new RandomAccessFile(file, "r");
       // 遍历分块,依次向每一个分块写入数据
       for (int i = 0; i < chunkNum; i++) {
           // 创建分块文件,默认文件名 path + i,例如chunk1  chunk2
           File chunkFile = new File(chunkFilePath + i);
           //分块文件写入流
           RandomAccessFile file_rw = new RandomAccessFile(chunkFile, "rw");
           int len = -1;
           // 向分块文件写入数据
           while ((len = file_r.read(bytes)) != -1) {
               file_rw.write(bytes, 0, len);
               // 写满就停
               if (chunkFile.length() >= chunkSize) {
                   break;
               }
           }
       }
       file_r.close();
       System.out.println("写入分块文件完毕");
   }

文件合并流程

  1. 找到要合并的文件并按文件分块的先后顺序排序
  2. 创建合并文件
  3. 依次从合并的文件中读取数据冰箱合并文件写入数据
  • 文件合并的测试代码
void testMerge() throws IOException {
       // 块文件目录
       File chunkFolder = new File("D:\\video\\chunk\\");
       // 源文件
       File sourceFile = new File("C:\\Users\\thirty\\Videos\\Captures\\1.mp4");

       // 文件名升序排序
       File[] files = chunkFolder.listFiles();
       List<File> fileList = Arrays.asList(files);
       // 合并文件
       File mergeFile = new File("D:\\video\\chunk\\1.mp4");
       Collections.sort(fileList, Comparator.comparingInt(o -> Integer.parseInt(o.getName())));
       // 用于写文件
       RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
       // 缓冲区
       byte[] buffer = new byte[1024];
       // 合并文件
       for (File chunkFile : fileList) {
           RandomAccessFile raf_read = new RandomAccessFile(chunkFile, "r");
           int len;
           while ((len = raf_read.read(buffer)) != -1) {
               raf_write.write(buffer, 0, len);
           }
           raf_read.close();
       }
       raf_write.close();
       // 判断合并后的文件是否与源文件相同
       FileInputStream fileInputStream = new FileInputStream(sourceFile);
       FileInputStream mergeFileStream = new FileInputStream(mergeFile);
       //取出原始文件的md5
       String originalMd5 = DigestUtils.md5Hex(fileInputStream);
       //取出合并文件的md5进行比较
       String mergeFileMd5 = DigestUtils.md5Hex(mergeFileStream);
       if (originalMd5.equals(mergeFileMd5)) {
           System.out.println("合并文件成功");
       } else {
           System.out.println("合并文件失败");
       }
   }