读取Base64编码邮件附件时readAllBytes读取不完整问题求助
解决Base64邮件附件读取不全的问题
核心问题分析
你遇到的readAllBytes()仅读取8KB内容的问题,根源是JavaMail 1.6.2版本中Base64InputStream的实现缺陷——该版本的流在available()方法中硬编码返回8192,而readAllBytes()依赖这个值预估缓冲区大小,导致只读取了第一块数据。逐字节读取不受available()的限制,因此能完整读取附件内容。
具体解决思路
1. 升级JavaMail依赖到修复版本
JavaMail 1.6.2是较旧版本,后续版本已修复该Base64InputStream问题。建议升级到兼容的最新稳定版本:
- 若迁移到Jakarta EE规范,使用
jakarta.mail:
<dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>2.0.1</version> <!-- 或更高稳定版本 --> </dependency>
- 若需保留javax命名空间,至少升级到
javax.mail:1.6.7(该版本已修复相关bug)。
2. 替换流读取方式(不升级依赖的临时方案)
如果暂时无法升级依赖,可使用不依赖available()返回值的读取方式:
- 用JDK9+支持的
transferTo()方法:
byte[] bs; try (InputStream is = mbp.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { is.transferTo(baos); bs = baos.toByteArray(); }
- 或用
BufferedInputStream包装流,提升读取性能:
byte[] bs; try (InputStream is = new BufferedInputStream(mbp.getInputStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { int len; byte[] buffer = new byte[8192]; while ((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } bs = baos.toByteArray(); }
3. 排查BouncyCastle兼容性
若使用BouncyCastle的邮件功能,需确保其版本与JavaMail兼容:
- Jakarta Mail 2.x搭配
org.bouncycastle:bcmail-jdk15on:1.70+ - javax.mail 1.6.x搭配
org.bouncycastle:bcmail-jdk15on:1.68+
同时避免手动替换JavaMail默认的DataHandler或InputStream实现,防止冲突。
4. 直接获取附件内容(绕过流读取)
尝试通过MimeBodyPart.getContent()直接获取解码后的字节数组,无需通过流读取:
Object content = mbp.getContent(); if (content instanceof byte[]) { byte[] bs = (byte[]) content; // 处理附件内容 }
内容的提问来源于stack exchange,提问作者chris01
相关产品推荐
相关产品推荐

