Huffman解压æ、ø、å等特殊字符出现乱码问题求解
问题根因
- 你提到的
æ、ø、å、•等字符在UTF-8编码下为变长存储,长度为2~3字节,你默认所有字符占1字节的逻辑存在问题。 - 你的IO代码未显式指定编码,
FileWriter默认使用操作系统本地编码做字符转码,导致单字节值被错误映射为多字节乱码。
具体修复方案
1. 显式指定IO编码(对应你补充的第一个问题)
将原有BufferedWriter初始化代码替换为显式指定UTF-8的实现:
// Java 7+ 版本,无需额外捕获编码异常 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFileName), StandardCharsets.UTF_8)); // 兼容Java 6及更早版本写法 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFileName), "UTF-8"));
如果你的哈夫曼逻辑本身是按二进制字节处理的,更推荐直接使用字节输出流避免不必要的字符转码,性能更高也不会出转码错误:
// 替换原有BufferedWriter相关全部逻辑 FileOutputStream fos = new FileOutputStream(newFileName); // 叶子节点写入逻辑替换为直接写字节 if (node.isLeaf()) { fos.write(node.getAByte()); node = root; } // 最后关闭输出流 fos.close();
2. 对齐压缩、解压逻辑
根据你压缩阶段的处理逻辑,保证两边规则完全一致:
- 如果压缩时是按原始文件的二进制字节统计频率(每个字节作为独立单元处理,不感知字符编码),解压时直接写二进制字节即可,不需要做任何字符转码,解压后文件和原文件二进制完全一致就不会有乱码。
- 如果压缩时是按UTF-8字符统计频率,你当前长度为256的
codeTable完全无法覆盖多字节字符,需要将编码表替换为支持全Unicode字符的HashMap结构,同时调整压缩、解压逻辑按字符粒度处理。
内容的提问来源于stack exchange,提问作者Kristina
相关产品推荐
相关产品推荐

