附件上传增加了附件二进制方式

Blade 已结 1 168
2930417211
2930417211 剑圣 2025-08-19 13:00

一、该问题的重现步骤是什么?

1. 增加了附件二进制方式

2. 

3.


二、你期待的结果是什么?实际看到的又是什么?

为了适配附件分片上传,附件上传增加二进制流的方式,测试发现txt文本上传可以正常打开,jpg文件上传无法正常打开,原始jpg文件是101kb,上传完成之后变成143kb。

三、你正在使用的是什么产品,什么版本?在什么操作系统上?

Bladex联合版, 4.5.0.RELEASE,Linxu系统

四、请提供详细的错误堆栈信息,这很重要。

image.png

原始文件:

image.png

上传合并成功之后的文件
image.png

image.png

五、若有更多详细信息,请在下面提供。

/**
 * 分片信息校验之后开始分片上传文件,接受二进制流
 * <p>专用</p>
 * @return
 */
@PostMapping(
    value="/uploadChunkOctetStream",
    consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE
)
public R<FileChunkCheckResponse> uploadChunkOctetStream(HttpServletRequest request, @Parameter(description = "文件的唯一标识", required = true) @RequestParam String identifier,
                                           @Parameter(description = "分块的序号,从0开始", required = true) @RequestParam Integer index,
                                           @Parameter(description = "分块大小,最后一块可能小于该值", required = true) @RequestParam Long chunkSize,
                                           @Parameter(description = "文件名,传入的文件名", required = true) @RequestParam String fileName,
                                           @Parameter(description = "分块的总数量,依据chunkSize计算", required = true) @RequestParam Integer totalChunks,
                                           @Parameter(description = "文件总大小", required = true) @RequestParam Long totalSize) throws IOException{
    FileChunkRequest fileChunkRequest = FileChunkRequest.builder()
       .identifier(identifier)
       .chunkNumber(index+1)
       .chunkSize(chunkSize)
       .filename(fileName)
       .totalChunks(totalChunks)
       .currentChunkSize(chunkSize)
       .totalSize(totalSize)
       .build();
    FileChunkCheckResponse upload = chunkService.upload(fileChunkRequest,request.getInputStream());
    return R.data(upload);
}

public FileChunkCheckResponse upload(FileChunkRequest fileChunkRequest, InputStream inputStream) {
    String identifier = fileChunkRequest.getIdentifier();
    String path = chunkFileProperties.getChunkPath() + File.separator + identifier;
    // 校验 chunkNumber 合法性
    int chunkNumber = fileChunkRequest.getChunkNumber();
    int totalChunks = fileChunkRequest.getTotalChunks();
    if (chunkNumber < 0 || chunkNumber > totalChunks) {
       throw new IllegalArgumentException("Invalid chunk number: " + chunkNumber);
    }
    boolean exist = FileUtil.exist(path);
    if (!exist) {
       // 创建文件夹
       FileUtil.mkdir(path);
    }
    String chunkFilePath = path + File.separator + chunkNumber;
    File chunkFile = new File(chunkFilePath);
    try (OutputStream outputStream = new FileOutputStream(chunkFilePath)) {
       byte[] buffer = new byte[8192];
       int len;
       while ((len = inputStream.read(buffer)) != -1) {
          outputStream.write(buffer, 0, len);
       }
       // 保存分片信息
       Chunk chunk = getChunk(fileChunkRequest.getIdentifier(), fileChunkRequest.getChunkNumber());
       if (Func.isEmpty(chunk)) {
          chunk = new Chunk();
       }
       chunk.setChunkNumber(fileChunkRequest.getChunkNumber());
       chunk.setChunkSize(fileChunkRequest.getChunkSize());
       chunk.setCurrentChunkSize(fileChunkRequest.getCurrentChunkSize());
       chunk.setFilename(fileChunkRequest.getFilename());
       chunk.setIdentifier(fileChunkRequest.getIdentifier());
       chunk.setRelativePath(path);
       chunk.setTotalChunks(fileChunkRequest.getTotalChunks());
       chunk.setTotalSize(fileChunkRequest.getTotalSize());
       baseMapper.insertOrUpdate(chunk);
       // 查询所有分块
       List<Chunk> chunkList = this.getChunkList(fileChunkRequest.getIdentifier());
       List<Integer> chunkNumberList = chunkList.stream().mapToInt(Chunk::getChunkNumber).boxed().toList();
       FileChunkCheckResponse response = FileChunkCheckResponse.builder().uploaded(chunkNumberList).build();
       // 是否上传完成
       if (chunkNumberList.size() == totalChunks) {
          response.setNeedMerge(Boolean.TRUE);
       }
       // 是否需要添加当前分块
       return response;
    }catch (IOException e) {
       log.error("Failed to write chunk file: {}", chunkFilePath, e);
       throw new ServiceException("Failed to write chunk file: " + chunkFilePath);
    }
}



1条回答
提交回复