1 void FileCompress::Uncompress(const char *file) 2 { 3 string Uncompressfile = file; 4 //我们要去掉其名字中点后的内容----用rfind 5 size_t pos = Uncompressfile.rfind('.'); 6 assert(pos != string::npos); 7 //找到pos位置,往后删 8 Uncompressfile.erase(pos); 9 10 //我们最后要做教研,所以不能直接覆盖原文件,需要生成一个新的文件。 11 Uncompressfile += ".unhuffman"; 12 13 //这里我们需要一个写new文件,一个读old文件。 14 ifstream f_in(file); 15 ofstream f_out(Uncompressfile.c_str()); 16 17 //我们要明确!!!树已经没有了!!! 18 //因为编码函数的树在函数执行结束后就被析构了!!! 19 //那么还好,我们还有哈希表,可以再重建一棵树。 20 HuffmanTree<CharInfo> MyHuffman(_hashInfos, 256, CharInfo(0)); 21 22 //**************我们需要记录我们压缩的字符数*********************** 23 //我们要去哪里找呢???? 24 //十分重要!!!!!!!! 25 //在根节点里,因为根节点里放了所有字符的总个数!!! 26 27 Node *cur = MyHuffman.GetRoot(); 28 29 //需要注意!!!!! 30 //如果这么写会出问题!!! 31 //因为char范围为-128 -- 127 32 //但是 有些字符的值是大于127的,也就是说会在char下显示负数 33 //那么哈希表[负]就会找到一个不存在的位置,就会非0非1 34 //然后会报错(感觉python就没这问题,数组下标为-,倒着来就完事。 35 //但是要注意也不能声明为unsigned char 因为EOF的值为-1,所以!!!! 36 //在每次需要用到_c做下标时,编程unsigned char 37 char _c; 38 string code_all; 39 int count = cur->_val._count; 40 41 //获得字符串并且明确——0左1右,没找到叶子,cur回根,往文件输入。 42 while ((_c = f_in.get()) != EOF) 43 { 44 for (size_t i = 0; i < 8; i++) 45 { 46 if ((_c & 1) == 0)//'1' 47 cur = cur->_left; 48 else //'0' 49 cur = cur->_right; 50 //叶子 51 if (cur->_left == NULL & cur->_right == NULL) 52 { 53 f_out.put(cur->_val._ch); 54 cur = MyHuffman.GetRoot(); 55 if (--count == 0) 56 break; 57 } 58 _c >>= 1; 59 } 60 } 61 62 f_in.close(); 63 f_out.close(); 64 }
有一点很需要注意:
//**************我们需要记录我们压缩的字符数***********************
//我们要去哪里找呢????
//十分重要!!!!!!!!
//在根节点里,因为根节点里放了所有字符的总个数!!!
那么现在还有两个问题:
1.
//问题1
//为什么文件读写中,不报错,但是写出来文件写着写着就没有内容了。
2.
//问题2
//我们要注意,我们应用的目的是!
//要将文件压缩,压缩后产生一个压缩文件。
//要将压缩文件解压,解压后还原文件。
//但是我们要明确,在解压缩时,我们得不到压缩时的哈希表
//所以,我们需要在压缩时,将压缩时生成的哈希表写入到压缩文件中。
//所以哈希表的压缩要写在所有文件之前。
//**********最简单的方式是直接把全部写进去,但是比较大。一口气写256个CharInfo**************
//不太好
//方法二:创建个临时结构tmpinfo 里面只放count和ch
//解压缩也要遵循tmpinfo的结构取,结束标识为一个count=-1的tmpinfo
//要区分 文本读写 和 二进制读写
下次公布问题解决思路。