霍夫曼压缩读取文件不会复制二进制文件c++中的所有字节

Huffman compression reading file does not copy all the bytes in the binary file c++

本文关键字:c++ 字节 二进制文件 复制 读取 压缩 文件 霍夫曼      更新时间:2023-10-16

我的程序是霍夫曼压缩,除了一件烦人的事情外,一切都很好。当我从压缩文件中读取字节时,只有大约三分之一的字节被复制和解压缩(返回到正常文本)。我真的不知道问题出在哪里。以下是从文件中读取字节并将其返回到STL容器的函数:

template<class Container>
Container readcompressfile(string ifileloc) {
    ifstream ifile(ifileloc);
    if (!ifile) {
        throw runtime_error("Could not open " + ifileloc + " for reading");
    }
    noskipws(ifile);
    return Container(istream_iterator<uint8_t>(ifile), istream_iterator<uint8_t>());
}

下面是我在解压函数中调用它的方法(如果它很重要的话,它会调用我包含在它下面的另一个函数):

void decompressfile(string loc) {
        vector<uint8_t> vecbytes(readcompressfile<vector<uint8_t>>(ifilelocation)); // Here is where I'm using the above function
        vector<uint8_t>::iterator iter = vecbytes.begin();
        uint8_t ctr = 0xFF;
        bitset<8> b2 = 0;
        string code = "";
        for (; iter != vecbytes.end(); ++iter) {
            b2 = ctr & *iter;
            for (int i = 7; i >= 0; i--) {
                code += to_string(b2[i]);
            }
        }
        decodetext(code, loc);
    }
    //Reads bits and outputs string
    void decodetext(string codetext, string ofileloc) {
        string code = "";
        string text = "";
        char lett;
        for each (char ct in codetext) {
            code += ct;
            lett = returncharmap(code);
            if (lett != NULL) {
                text += lett;
                code = "";
            }
        }
        ofstream ofile(ofileloc);
        ofile << text;
        ofile.close();
    }

压缩函数将一个1和0的字符串转换为位(我将它们打包为字节),然后将其存储在文件中(这很好),至于解压缩,正如你所注意到的,我在readcompressfile(string ifileloc)函数中读取了二进制文件,然后将它放在vector<uint8_t>容器中,再将其转换回一个1或0的字符串,然后再次转换回文本,并且被复制的字节被很好地解压缩。

我显示了字符串前后的大小,这是的结果

注意:readcompressfile(string ifileloc)函数是我从stackoverflow上的某个人那里复制的,因为它解决了我之前遇到的一个问题。

我猜您运行的是Windows,它会将文本流中的^Z字符(这是ifstream的默认模式)解释为文件结束指示符。

代替:

 ifstream ifile(ifileloc);

用途:

 ifstream ifile(ifileloc, ifstream::in | ifstream::binary);

正如下面的评论所指出的,Windows平台还将在文本模式下将"rn"字符序列转换为单个字符"n"