处理邮件附件时,为何BufferedReader/Writer生成损坏的.xls,而Buffered流正常?
问题解答:字符转换导致二进制附件损坏的原因
是的,完全是字符流的转换操作导致了.xls文件的损坏,具体原因可以从文件类型差异和字符流的工作原理来拆解:
1. 文本文件与二进制文件的本质区别
.xml和.txt属于纯文本文件:它们的内容由符合特定字符编码(如UTF-8、GBK)的字节序列组成,每一组字节对应可识别的字符,用字符流处理时能准确完成字节与字符的双向转换。.xls是二进制格式文件:这类文件包含大量非字符的二进制数据(比如文件头标识、格式控制字节、压缩的表格数据块等),这些字节本身不对应任何可打印字符,也不符合常规字符编码规则。
2. 原有字符流代码的问题
你原来的代码通过InputStreamReader将附件字节流转为字符流,再用FileWriter写回文件:
InputStream inputStream = part.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); BufferedWriter writer = new BufferedWriter(new FileWriter(file));
这个过程触发了不必要的字符编码转换:
InputStreamReader会尝试将读取到的字节按默认(或指定)编码解析为字符,但.xls里的二进制字节很多是无效的编码序列,Reader会用替换字符(比如�)替代无法解析的字节,甚至直接丢弃、篡改原始数据。- 后续
FileWriter把字符转回字节写回文件时,原始二进制结构已被破坏,文件的关键格式信息丢失,自然无法被LibreOffice或Apache POI识别。
3. saveFile方法正常的原因
MimeBodyPart.saveFile()内部使用BufferedInputStream和BufferedOutputStream做纯字节流操作:
- 它直接读取附件的原始字节,不做任何编码转换或字符解析,完全保留了文件的二进制结构和数据。
- 写入文件时也是原样输出读取到的字节,生成的文件和原始附件完全一致,因此能正常打开和读取。
总结建议
处理邮件附件时,除非你100%确定附件是纯文本格式,否则都应该用字节流直接读写,避免字符流导致二进制文件损坏——这也是saveFile能通用处理所有附件类型的核心原因。
内容的提问来源于stack exchange,提问作者kozeljko
相关产品推荐
相关产品推荐

