霍夫曼:无法解压像“æ”、“ø”、“å”和“•”这样的字符

Huffman: Can't decompress characters like 'æ', 'ø', 'å' and '•'

我正在处理我的 Huffman 压缩(或者此时的解压),但我无法正确解压“æ”、“ø”、“å”和“•”等字符。字符'æ'被解压为两个符号'ᅢᆭ'。知道应该做什么吗?

编辑: 我认为这可能与 BufferedWriter 和 InputStream(以及其他)有关。我可能需要用 UTF-8 或其他方式读写?我该怎么做?

编辑 2::在一些求助热线的帮助下,我发现“ᅢ”和“ᆭ”作为单独的字符写入文件。 'ø' 是否大于 1 个字节,也许我假设每个字符在某处都是 1 个字节?

public static void decompressFile() throws IOException {

    
    byte[] compressedBytes = //somecode
    int[] frequencyTable = //somecode

    HuffmanNode root = //some code

    //Generating code table
    String[] codeTable = new String[256];
    Huffman.getCodeTable(codeTable, root, "");

    DataInputStream inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream("[//thecompressedfile]"
    BitInputStream bitInputStream = new BitInputStream(inputStream, compressedBytes.length);

    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFileName));


    HuffmanNode node = root;
    int bit;


    while ((bit = bitInputStream.readBit()) != -1) {
        //int bit = bitInputStream.readBit();
        System.out.print(bit + "");

        if (bit == 0) {
            node = node.getLeft();
            if (node.isLeaf()) {
                bufferedWriter.write(node.getAByte());
                node = root;
            }
        } else if (bit == 1) {
            node = node.getRight();
            if (node.isLeaf()) {
                bufferedWriter.write(node.getAByte());
                node = root;
            }
        }
    }

    bufferedWriter.close();
}

您使用 InputStream 读取并使用 Writer 写入。第一个用于读取二进制数据,第二个用于写入文本。当您调用 bufferedWriter.write(node.getAByte()).

时,您正在进行隐式转换

换句话说,您将二进制数据解释为 ISO-8859-1,因为您基本上是将一个字节转换为 char(技术上是 int 用于...奇怪的原因)。然后你用任何平台默认编码写回它。

这会弄乱您的文本,除非它碰巧是 ISO-8859-1 编码并且平台默认编码是相同的。

更好的方法是将其始终视为二进制数据(如果它真的是文本也没关系,只要您不关心解释您的文本代码,你似乎没有这样做)。由于霍夫曼编码作用于字节流,这也更符合您对数据所做的操作。

为此,将 Writer 替换为 OutputStream(即 FileOutputStream,出于性能原因可能包含在 BufferedOutputStream 中)。