看见好几个别班的同学都在写java的课程设计,写的都是各种小游戏,我也就想写个,可我不想写小游戏,想了好久才想到写这个数据压缩。然后就查查资料就写了,但后来发现我班没有课程设计,所以就没添加界面。写完之后还是有收获的,完全刷新了我对数据压缩方法的印象。
我以前以为数据压缩就是 000000111100111 表示成 60412031这种形式再存入内存,如今才知道存入内存的是编码。
我在写的时候用的是整型表示的文件长度,这限制了所能压缩的文件的体积。换成BigInteger就可以压缩更大的文件了。
参考资料:http://www.cnblogs.com/keke2014/p/3857335.html
源代码下载:http://download.youkuaiyun.com/detail/gyhguoge01234/9696065
HuffmanCompress.java:
import java.util.*;
import java.io.*;
public class HuffmanCompress {
private PriorityQueue<HufTree> queue = null;
//压缩函数
public void compress(File inputFile, File outputFile){
Compare cmp = new Compare();
queue = new PriorityQueue<HufTree>(12,cmp);
//映射字节及其对应的哈夫曼编码
HashMap<Byte,String> map = new HashMap<Byte,String>();
//文件中含有的字符的种类数
int i,char_kinds = 0;
int char_temp,file_len = 0;
FileInputStream fis = null;
FileOutputStream fos = null;
ObjectOutputStream oos = null;
//哈夫曼树节点个数
int node_num;
HufTree[] huf_tree = null;
String code_buf = null;
//临时存储字符频度的数组
TmpNode[] tmp_nodes = new TmpNode[256];
for(i = 0; i < 256; ++i){
tmp_nodes[i] = new TmpNode();
tmp_nodes[i].weight = 0;
tmp_nodes[i].uch = (byte)i;
}
try {
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
oos = new ObjectOutputStream(fos);
//统计字符频度,计算文件长度
while((char_temp = fis.read()) != -1){
++tmp_nodes[char_temp].weight;
++file_len;
}
fis.close();
Arrays.sort(tmp_nodes);
//排序后就会将频度为0的字节放在数组最后,从而去除频度为0的字节
//同时计算出字节的种类
for(i = 0; i < 256; ++i){
if(tmp_nodes[i].weight == 0)
break;
}
char_kinds = i;
//只有一种字节的情况
if(char_kinds == 1){
oos.writeInt(char_kinds);
oos.writeByte(tmp_nodes[0].uch);
oos.writeInt(