JavaMail写入eml时抛出UnsupportedOperationException(charset=iso-2022-cn)
解决Java写入ISO-2022-CN字符集EML文件的异常问题
这个问题我之前踩过坑,本质原因很明确:Java自带的ISO2022_CN字符集实现只支持解码(读取)操作,完全不支持编码(写入)——你报错里的sun.nio.cs.ext.ISO2022_CN.newEncoder()抛出UnsupportedOperationException,就是最直接的证据。
给你几个亲测有效的解决思路:
转换字符集后写入(最简便)
先把ISO-2022-CN编码的内容解码成Java字符串,再用支持编码的通用字符集(比如UTF-8、GBK)写入磁盘。注意如果要保留邮件的可读性,记得同步修改EML文件里的Content-Type头,把charset="iso-2022-cn"改成你实际使用的字符集。
示例代码:import java.nio.file.Files; import java.nio.file.Paths; import java.nio.charset.StandardCharsets; // 读取原EML内容 byte[] rawBytes = Files.readAllBytes(Paths.get("your-input.eml")); String content = new String(rawBytes, "ISO-2022-CN"); // 用UTF-8写入新文件 Files.write(Paths.get("your-output.eml"), content.getBytes(StandardCharsets.UTF_8));借助JavaMail库处理(最专业)
如果你的场景是处理邮件格式,JavaMail库对各种邮件字符集的兼容性处理比原生Java IO靠谱得多。它会自动帮你处理字符集的编码转换,不用手动操心底层编码器的问题。
示例代码:import javax.mail.Session; import javax.mail.internet.MimeMessage; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; Session session = Session.getDefaultInstance(new Properties()); // 读取原EML MimeMessage msg = new MimeMessage(session, new FileInputStream("your-input.eml")); // 直接写入新文件,JavaMail会自动处理字符集编码 msg.writeTo(new FileOutputStream("your-output.eml"));手动实现ISO-2022-CN编码器(不推荐)
如果你有必须用ISO-2022-CN写入的特殊需求,只能自己实现符合该字符集规范的编码器,但这个工作量大且容易出错,除非业务强制要求,否则不建议走这条路。
额外提醒:如果你的EML是多部分邮件(包含附件、多段不同编码的文本),建议用JavaMail解析后逐个处理内容部分,再重新组装写入,避免直接替换字节导致邮件结构损坏。
内容的提问来源于stack exchange,提问作者Sathish Kumar
相关产品推荐
相关产品推荐

