根据霍夫曼编码,压缩和解压文件字节数组的过程

哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

哈夫曼编码,主要目的是根据使用频率来最大化节省字符(编码)的存储空间。
本文主要利用霍夫曼编码来压缩字节数组(可以是任何文件),同时修复了尚硅谷韩顺平老师的bug,对于字节数组最后一位的补位问题
流程主要是
1.源字节数组—>根据各个字节出现的频次,创建有权重(即该字节出现的次数)的二叉树结点,存储到列表中
2.根据上一步的列表list,创建霍夫曼树(创建过程原理可参照百度,原理较为简单),获得根节点
3.获得霍夫曼树后,重新编码,根据路径左0右1的原则,对每个字符的霍夫曼编码存储到map中,便于后续压缩
4.对照编码map,对源字节数组重新编码,获得一串二进制数组
5.编码后的二进制数组,每8位存储为一个字节,得到的结果就是编码压缩后的新字节数组。
6.解码:先将压缩后的字节数组依次读取转成二进制字符串
7.反转map,依次读取二进制字符串,还原源字节数组

附上源码

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HuffmanCode {
   
	public static void main(String[] args) {
   
		
		zipFile("G:/src.bmp", "G:/dest.zip");
		System.out.println("压缩成功");
		
		unZipFile("G:/dest.zip", "G:/src2.bmp");
		System.out.println("解压成功");
		
		/*
		String content = "i like like like java do you like a javae";
//		String content = "你好";
		
		byte[] contentBytes = content.getBytes();
		System.out.println("原文件字节数组:"+Arrays.toString(contentBytes));
//		System.out.println("原文件字节数组长度="+contentBytes.length);//40
		
		byte[] huffmanCodeBytes = huffmanZip(contentBytes);
		System.out.println("压缩后的数组为:"+Arrays.toString(huffmanCodeBytes));
		
		byte[] decodeBytes = decode(huffmanCodes, huffmanCodeBytes);
		System.out.println("解码后的结果:"+new String(decodeBytes));
		*/
		
		/*
		List<Node> nodes = getNodes(contentBytes);
		System.out.println(nodes);
		
		Node huffmanTreeRoot = createHuffmanTree(nodes);
		huffmanTreeRoot.preList();
		
		Map<Byte, String> huffmanCodes = createHuffmanCode(huffmanTreeRoot);
		System.out.println(huffmanCodes);
		
		byte[] huffmanCodeBytes = zip(contentBytes, huffmanCodes);
		System.out.println(Arrays.toString(huffmanCodeBytes)); //只有17长度*/
	}
	
	//存放哈夫曼编码表
	static Map<Byte, String> huffmanCodes = new HashMap<>();
	//二进制字符串8位存放一个字节,存放编码后的最后一个数字位数
	static int lastNumCap;
	
	//解压文件
	public static void unZipFile(String src,String dest) {
   
		InputStream is = null;
		ObjectInputStream ois = null;
		OutputStream os = null;
		
		try {
   
			is = new FileInputStream(src);
			ois = new ObjectInputStream(is);
			byte[] srcBytes = (byte[]) ois.readObject();//读取的编码后的字节数组
			Map<Byte, String> huffmanCodes = (Map<Byte, String>) ois.readObject();//读取编码表
			byte[] destBytes = decode(huffmanCodes, srcBytes);
			
			os = new FileOutputStream(dest);
			os.write(destBytes);
			os.flush();
		} catch (Exception e) {
   
			System.out.println(e.getMessage());
		}finally {
   
			try {
   
				os.close();
				ois.close();
				is.close();
			} catch (IOException e) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值