Springboot分片上传

74 阅读2分钟
 public static void main(String[] args) throws IOException {

    File sourceFile = new File("D:\\44.mp4");
    String chunkFolder = "D:\\IDM\\videos\\chunks\\";
    File f = new File(chunkFolder);
    if (!f.exists()){
        f.mkdirs();
    }
    long shareSize = 1024 * 1024 * 10; // 分片的大小,单位为字节
    System.out.println("分片大小: " + shareSize);

    try (RandomAccessFile randomAccessFileReader = new RandomAccessFile(sourceFile, "r");FileChannel fileChannelReader = randomAccessFileReader.getChannel()) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        long total = (long) Math.ceil(sourceFile.length() * 1.0 / shareSize);
        System.out.println("分片总数: " + total);

        for (int i = 0; i < total; i++) {
            File chunkFile = new File(chunkFolder + i);
            System.out.println("分片: " + (i + 1) + ", chunkFile: " + chunkFile.getName());

            try (RandomAccessFile randomAccessFileWriter = new RandomAccessFile(chunkFile, "rw");
                 FileChannel fileChannelWriter = randomAccessFileWriter.getChannel()) {
                int len;
                buffer.clear();
                while ((len=fileChannelReader.read(buffer)) != -1) {
                    //改为读模式
                    buffer.flip();
                    fileChannelWriter.write(buffer);
                    //改为写模式
                    buffer.compact();
                    //如果分片的大小>=分片的大小,读下一块
                    if (chunkFile.length() >= shareSize) {
                        break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
    //合并文件
    mergeFile(new File(chunkFolder));
}


 /**
 * 合并块文件
 * @param chunkFolder
 */
public static void mergeFile(File chunkFolder) throws IOException {
    //块文件夹下文件列表
    File[] files = chunkFolder.listFiles();
    assert files != null;
    List<File> fileList = Arrays.stream(files).sorted(
            Comparator.comparing(o -> Long.valueOf(o.getName())))
            .collect(Collectors.toList());
    //合并的文件
    File mergeFile = new File("D:\\IDM\\videos\\chunks\\java_merge.mp4");
    //创建新文件
    boolean success = mergeFile.createNewFile();
    //创建写对象
    RandomAccessFile randomAccessFileWriter = new RandomAccessFile(mergeFile, "rw");
    byte[] bytes = new byte[1024];
    for (int i = 0; i < fileList.size(); i++) {
        File chunkFile = fileList.get(i);
        logger.info("合并------>分片:{},chunkFile:{}", i + 1, chunkFile.getName());
        RandomAccessFile randomAccessFileReader = new RandomAccessFile(chunkFile, "r");
        int len;
        while ((len = randomAccessFileReader.read(bytes)) != -1) {
            randomAccessFileWriter.write(bytes, 0, len);
        }
        randomAccessFileReader.close();
    }
    randomAccessFileWriter.close();
    Arrays.stream(files).forEach( f->{
        f.delete();
    } );
}
 /*另外一种方式*/
@GetMapping("/t")
public String test() {
 String filePath = "D:\testdata.zip";
 String fileName = "testdata.zip";
 File sourceFile = new File(filePath);
 long shareSize = 1024 * 1024;
 String path = "D:\test\";
 File f = new File(path);
 if (!f.exists()) {
     f.mkdirs();
 }
 long total = 0;
 try (RandomAccessFile randomAccessFileReader = new RandomAccessFile(sourceFile, "r"); FileChannel fileChannelReader = randomAccessFileReader.getChannel()) {
     ByteBuffer buffer = ByteBuffer.allocate(1024);
     total = (long) Math.ceil(sourceFile.length() * 1.0 / shareSize);
     System.out.println("分片总数: " + total);
     byte[] bytes = new byte[1024];
     for (int i = 0; i < total; i++) {
         File chunkFile = new File(path + i);
         log.info("分片:{},chunkFile:{}", i + 1, chunkFile.getName());

         //创建一个写对象
         RandomAccessFile randomAccessFileWriter = new RandomAccessFile(chunkFile, "rw");
         int len;
         while ((len = randomAccessFileReader.read(bytes)) != -1) {
             randomAccessFileWriter.write(bytes, 0, len);
             //如果分片的大小>=分片的大小,读下一块
             if (chunkFile.length() >= shareSize) {
                 break;
             }
         }
         randomAccessFileWriter.close();
     }
 } catch (IOException e) {
     e.printStackTrace();
 }
 long start = 0;
 for (int i = 0; i < total; i++) {
     long chunkStart = start + i * shareSize;
     File file = new File(path + i);
     FileItem item = new DiskFileItemFactory().createItem("file"
             , MediaType.MULTIPART_FORM_DATA_VALUE
             , true
             , file.getName());
     try (InputStream input = new FileInputStream(file);
          OutputStream os = item.getOutputStream()) {
         // 流转移
         IOUtils.copy(input, os);
     } catch (Exception e) {
         throw new IllegalArgumentException("Invalid file: " + e, e);
     }
     MultipartFile chunkFile = new CommonsMultipartFile(item);
     fileService.resumeUpload(chunkFile, chunkStart, fileName);
 }
 return "ok";
}


public String resumeUpload(MultipartFile file, long start, String fileName) {
 try {

     File directory = new File(UPLOAD_DIR);
     if (!directory.exists()) {
         directory.mkdirs();
     }
     File targetFile = new File(UPLOAD_DIR + fileName);
     RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "rw");
     FileChannel channel = randomAccessFile.getChannel();
     channel.position(start);
     channel.transferFrom(file.getResource().readableChannel(), start, file.getSize());
     channel.close();
     randomAccessFile.close();
     return "上传成功";
 } catch (Exception e) {
     System.out.println("上传失败: " + e.getMessage());
     return "上传失败";
 }
}