文件压缩(c++)

有关于文件压缩的思想和问题。

huffman tree不单单针对文件压缩,也可以用在其他地方
这里写图片描述
编码时候更关注叶子结点。
直接利用二叉树前中后序遍历二叉树找叶子结点,但前提是必须是三叉链。
生成Huffman编码:第一种是_infos[root->_w._ch]._code = code;//字符的ASCII码//将编码存入到叶子结点的权值的字符中
第二种是string& code = _infos[root->_w._ch]._code;//没有创建对象,没有拷贝,可读性变高

文件压缩
问题:
1.汉字不能正确压缩
因为汉字通常是由负数的ASCII码组成,_infos[]不能访问到。
只能强转(unsigned char)
问题1:存在汉字的文件,压缩时程序会崩,所以需要让程序支持汉字字符压缩。
打断点找存在汉字程序就会崩的问题所在。
只需要将_infos[root->_w._ch]._code改为_infos[(unsigned char)root->_w._ch]._code就可以了,是为了将负数值的ASCII码所对应的汉子字符读出。
源文件:
这里写图片描述
解压缩后的文件:
这里写图片描述
2.如果需要压缩的数据过多,就不能正确压缩
解压缩与文件的随机性有关。(!待解决!)
需要判断是压缩的问题还是解压缩的问题。。。
(1)没有解压缩完全
通过记录压缩的字符个数,与解压缩的字符个数比较,查看是否是解压缩的问题
一种可能是没有读的字符个数不足,说明解压缩时候读压缩文件有误。
另一种可能是压缩的写的字符个数不够,说明压缩时候写文件有误。

。。以上通过记录个数调试。。。
问题2:现阶段少部分的字符格式的文件是可以被压缩与解压缩的。
源文件:
这里写图片描述
压缩后的文件:
这里写图片描述
解压缩后的文件:
这里写图片描述
但是程序仍旧存在问题,如果文件内存的字符过多(具体的数值大小不清楚),就会出现问题。
压缩前:
这里写图片描述
解压缩后:
这里写图片描述
结果并不正确!
所以要解决问题,就要知道程序出错的位置,要测试看到底是压缩的过程出现问题还是解压缩的过程出现问题。
所以,为什么解压缩的时候解压缩的长度具有随机性?

提前遇到EOF。
文件格式。

文件没有读完,就提前遇到了EOF,为什么?
文本文件是可以读的,二进制文件——音频、视频、图片
文本文件通过EOF判断结束,一般来说,-1的ASCII码是不用的
文本文件里面不会出现-1,但二进制文件可能出现-1,所以不可以用EOF单纯判断结束。

解决方式:
feof()要比EOF多读一次。
feof()文件结束符,只有当文件结束或者错误的时候其返回的值是非零值,否则为零,比EOF好的地方在于省去了EOF判断是-1的时候会影响结果的情况。
所以将while循环的判断条件改为 !foef(fout) ,让ASCII码为-1的字符不会影响结果。

1.文本方式读写
2.二进制读写
文件系统——管理文件(FEOF——读到最后一次不会停,会多读一次)
会有接口来管理文件,比如说文件指针,下标移动读文件。

一般情况,先单独压缩,在单独解压缩。
压缩是没有问题,解压缩有问题,解压缩依赖Huffman tree,需要字符出现的次数。
为什么压缩与解压缩一起运行的时候解压缩没有出问题?
因为压缩与解压缩用的是同一个对象,即同一个Huffman tree,所以解压缩是有字符出现的次数是存在的。

但根源问题是在压缩的时候就要记录。
文本和二进制形式写,
这里写图片描述
所以两者占的空间是一样的。

文本形式
在压缩之后,写字符出现的次数到压缩文件,——解压缩时重建Huffman tree
char buffer[128];
for(size_t i=0;i<256;++i)
{
if(_infos[i]._count > 0)
{
fputc(_infos[i]._ch,fin);
fputc(’ ‘,fin);
itoa(_infos[i]._count,buffer,10);
fputs(buffer,fin);
fputc(‘\n’,fin);
}
}

字符分为可读和不可读的。。。。。
将次数读出来使用itoa变成字符串保存。
二进制形式
//为什么fwrite既有size还有count?
在内存的角度和磁盘的角度:
count 对象的number(个数),size是每一次准备写的每个对象的字节数。
二进制形式任意对象都可以写进去。

char buffer[128];
for(size_t i=0;i<256;++i)
{
if(_infos[i]._count > 0)
{
fwrite(&_infos[i],sizeof(CharInfo),1,fin);
}
}
二进制形式比文本形式所占空间更大。(不一定)

为什么二进制形式写进去所占的字节数更多?
这里写图片描述

文本形式必须以分隔符区分,而二进制形式字节数是固定的,当文本形式内容更多时,就会存在文本形式会占跟多的空间,二进制形式不需要分隔符区分字符,8个字节就表示一个字符,多出来的位用0补位(字节对齐)。所以文本形式比一定就比二进制形式所占空间小。

在类中定义类,内部类,但受到访问限定符的限,不暴露在外部。
这里写图片描述
为了传输节省带宽,就将Huffman tree中的内容存成配置文件,与压缩文件一起存。
先读入配置信息——字符出现的次数
循坏判断,一直读,如果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值