You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从CipherInputStream创建FormDataBodyPart时文件大小为0的问题

解决FormData传递解密流后对方收到空文件的问题

可能原因及对应解决方案

1. 流的读取指针位置异常

调试时如果已经读取过解密流(比如打印内容、校验长度),流的指针会移动到末尾,后续封装时就会读取不到内容。

  • 解决方案:
    • 如果是ByteArrayInputStream,调用reset()方法重置指针到起始位置;
    • 如果是CipherInputStream,因为它不支持reset(),需要重新调用decryptStream()获取新的流实例,避免复用已被读取过的流。

2. 未正确设置FormDataBodyPart的元数据

FormData需要明确指定文件的名称和Content-Type,否则服务端可能无法正确解析流:

// 示例:正确构建FormDataBodyPart
CipherInputStream decryptStream = decryptStream();
// 先将解密流转为ByteArrayInputStream并缓存内容(确保能重复读取)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = decryptStream.read(buffer)) != -1) {
    baos.write(buffer, 0, bytesRead);
}
decryptStream.close();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray());

FormDataBodyPart filePart = new FormDataBodyPart(
    FormDataContentDisposition.name("image").filename("encrypted-image.jpg").build(),
    byteArrayInputStream,
    MediaType.APPLICATION_OCTET_STREAM_TYPE
);

3. 未指定流的内容长度

服务端可能依赖Content-Length头来读取文件内容,如果流没有提供长度信息,会导致读取到空内容。

  • 解决方案:
    • 提前将解密流的内容读取到字节数组,通过字节数组构建ByteArrayInputStream,同时在FormDataBodyPart中指定内容长度:
byte[] fileBytes = baos.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileBytes);
FormDataBodyPart filePart = new FormDataBodyPart(
    FormDataContentDisposition.name("image").filename("encrypted-image.jpg").size(fileBytes.length).build(),
    byteArrayInputStream,
    MediaType.IMAGE_JPEG_TYPE // 根据实际图片类型设置
);

4. 流提前被关闭

确保在发送请求的整个过程中,解密流或缓存的字节流没有被提前关闭。比如,不要在构建FormDataBodyPart后立即关闭流,要等到请求发送完成后再执行关闭操作。

验证步骤

  1. 确认缓存后的字节数组长度大于0,证明解密后的内容有效;
  2. 发送请求前,重置ByteArrayInputStream的指针到起始位置;
  3. 检查服务端接收代码是否正确解析FormData,是否完整读取了流内容。

内容的提问来源于stack exchange,提问作者Fatima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 07:18:25