本章节中,主要讲自己动手压缩数据。我们通常使用的压缩方式是以zip为扩展名来压缩的。那么问题来了,在文件中存续数据的基本单位是什么?在doc,zip,txt,这些文件扩展名中,代表压缩文件的是那个 ?BMP格式的图片文件是经过压缩的吗?在Windows计算机经常使用的Shift-JIS编码中,一个半角英文或数字字符需要用几字节的数据来表示?
其实在文件中存续数据的基本单位是字节(1字节=8比特),在doc,zip,txt,这些文件扩展名中,代表压缩文件的是zip,BMP格式的图片文件是没有经过压缩的,在Windows计算机经常使用的Shift-JIS编码中,一个半角英文或数字字符需要用1字节(8比特)的数据来表示(半角英文,数字和符号都是用1字节表示的,汉字等全角字符用2字节表示)(shift-JIS是一种常用的日文字符编码方案,中文字符常用编码方案为GB2312,GB18030等)。
WINDOWS中常用的压缩文件扩展名是zip,当我们用电子邮件附件发送较大的文件时,文件就会被压缩,将用数码相机拍摄的照片保存到计算机中时,也会不知不觉的用到GPEG等压缩格式。文件是以字节为单位记录的,文件是字节数据的集合体,1字节(8比特)能够表示的字节数据共有256种,也就是二进制数的00000000~11111111所表示的范围。存储在文件中的数据,如果表示字符,那这个文件就是一个文本文件,如果表示图案,那这个文件就是一个图片文件,但无论如何,我们都可以认为文件就是一连串连续存储的字节数据。接下来我们来说一下游程编码的原理:假设我们要对AAAAAABBCDDEEEEEF,这个包含17个半角英文字符的文件进行压缩,虽然文件的内容没有什么意义,但它非常用来讲解压缩的原理。每个半角英文字符在文件中都占一个字节,因此这个文件的大小为17个字节,至于怎样压缩这个文件用任何方法都可以,只要让压缩后的文件的大小,小于17个字节就行了。嗯,那么就是用字符乘以重复次数来表示文件的内容。我们可以看到,在AAAAAABBCDDEEEEEF这串字符中,一些字符重复出现了多次,如果把重复出现的字符放在后面,就可以将那些表示为A6B2C1D2E5F1 。这样就只有12个字符了,即文件大小为12个字节,相当于原文件的12,除以17约等于70%压缩成功。所以说像这样将文件内容用数据乘以重复次数来表示的压缩方法称为游程编码,游程编码是一种很好压缩的方法。不过,在实际的文本文件中,很少有同一个字符,连续多次出现的情况。对于相同数据出现的情况较多的情况下,游程编码是比较好的,但它不适用于来压缩文本文件。第二种压缩方法是哈夫曼算法,哈夫曼算法是大卫哈夫曼于1952年提出的zip格式,也是使用哈夫曼算法来进行压缩的。要理解哈夫曼算法,我们首先需要舍弃一个半角英文,数字和符号占1字节的固有概念,一个文本文件中包含各种各样的字符,但每个字符出现的次数是不一样的。我们来举个例子,在一个文本文件中,A出现了100次,但Q只出现了三次,这是很普遍的现象。用哈夫曼算法压缩的重点在于,我们可以将出现次数多的数据用小于8比特的编码来表示,将出现次数少的数据用大于8比特的编码来表示,如果A和Q都用8比特来表示,那么文件的原始大小就是8比特100次+8比特3次==824比特,但如果我们能将,A用2比特来表示,将Q用10比特来表示,那么压缩后的数据大小就是2比特100次+10比特3次=230比特。但是但是无论,是不足8比特的数据还是超过8比特的数据,最终都要以8比特为单位存储到文件中,因此磁盘按1字节来单位存储数据的事实是无法改变的。
具体算法就不再一一举了。还有一种是使用树来构建哈夫曼编码。具体就不一一说了。