package com.gxmedu.huffman_code;import java.io.*;
import java.util.*;/*** @author 郭学明* @version 1.0*/
public class HuffmanCode {public static void main(String[] args) {HuffmanCode huffmanCode1 = new HuffmanCode();String s1= "i like like like java do you like a java";
//        s1 = "hello,world";
//        List<Node> nodes = huffmanCode1.getNodes(s1.getBytes());
//        Node huffmanTree = huffmanCode1.createHuffmanTree(nodes);
//        huffmanCode1.getHuffmanCode(huffmanTree,"",huffmanCode1.huffmanCodeBuilder);
//       System.out.println(huffmanCode1.huffmanCode);byte[] result = huffmanCode1.zip(s1.getBytes());System.out.println(Arrays.toString(result));byte[] decompression = huffmanCode1.decompression(result,huffmanCode1.huffmanCode);System.out.println(new String(decompression));//        String compressionSrcPath = "D:\\chapter19_case\\WorldWarII.png";
//        String compressionDestPath = "D:\\chapter19_case\\WorldWarII.gxm";
//        String decompressionDestPath = "D:\\chapter19_case\\WorldWarII2.png";
//        huffmanCode1.compressionFile(compressionSrcPath,compressionDestPath);
//        huffmanCode1.decompressionFile(compressionDestPath,decompressionDestPath);}public class Node implements Comparable<Node>{private Byte data;private int weigh;private Node left;private Node right;public Node(Byte data, int weigh) {this.data = data;this.weigh = weigh;}public Byte getData() {return data;}public void setData(byte data) {this.data = data;}public int getWeigh() {return weigh;}public void setWeigh(int weigh) {this.weigh = weigh;}public Node getLeft() {return left;}public void setLeft(Node left) {this.left = left;}public Node getRight() {return right;}public void setRight(Node right) {this.right = right;}@Overridepublic String toString() {return "Node{" +"data=" + data +", weigh=" + weigh +'}';}@Overridepublic int compareTo(Node o) {return this.weigh - o.weigh;}}/***  1.将字节数组的元素进行次数统计,这个次数就是之后huffman tree结点的weigh,*  目标是得到一个ArrayList<Node>,这里我们用hashmap,key不能重复的特性,来统计出现次数。*/public List<Node> getNodes(byte[] bytes){HashMap<Byte, Integer> dataCount = new HashMap<>();Set<Map.Entry<Byte, Integer>> entries = dataCount.entrySet();for (byte b : bytes) {Integer count = dataCount.get(b);if(count == null){dataCount.put(b,1);}else{dataCount.put(b,count + 1);}}ArrayList<Node> nodes = new ArrayList<>();for (Map.Entry<Byte, Integer> entry : entries) {Node node = new Node(entry.getKey(), entry.getValue());nodes.add(node);}return nodes;}/***  2.生成huffman tree*/public Node createHuffmanTree(List<Node> nodes){while(nodes.size() > 1){Collections.sort(nodes);Node left = nodes.get(0);Node right = nodes.get(1);Node parent = new Node(null, left.weigh + right.weigh);parent.setLeft(left);parent.setRight(right);nodes.remove(left);nodes.remove(right);nodes.add(parent);}return nodes.get(0);}/***  3.生成huffman code,这里也用hashmap 存储*/private StringBuilder huffmanCodeBuilder = new StringBuilder();private HashMap<Byte,String> huffmanCode = new HashMap<>();public void getHuffmanCode(Node node,String code,StringBuilder sb){StringBuilder stringBuilder2 = new StringBuilder(sb);stringBuilder2.append(code);
//        HashMap<Byte, String> huffmanCode = new HashMap<>();if(node != null){if(node.data == null){getHuffmanCode(node.left,"0",stringBuilder2);getHuffmanCode(node.right,"1",stringBuilder2);}else{//            stringBuilder2.append(code);huffmanCode.put(node.data,stringBuilder2.toString());}}}/***  4.根据HuffmanCode将传入的字节数组进行压缩转换*/public byte[] huffmanCodeBytes(byte[] bytes,HashMap<Byte,String> huffmanCode){StringBuilder stringBuilder = new StringBuilder();for (byte b :bytes) {String s = huffmanCode.get(b);stringBuilder.append(s);}int length = stringBuilder.length();
//        这里给数组多加最后一位,用来记录最后一个字符串的长度
//        比如说最后一个字符串是"0001"或者"001",但是在byte[]中存的都是1,
//        这样就会导致huffmanCode解码错误。byte[] huffmanCodeBytes = new byte[(length + 7)/8 + 1];
//        String s = stringBuilder.toString();int zipIndex = 0;int lastStringLength = 0;for (int i = 0; i < length ; i += 8) {String s = "";if(i + 7 < length){s = stringBuilder.substring(i, i + 8);}else{s = stringBuilder.substring(i);
//                 lastStringLength = s.length();}lastStringLength = s.length();huffmanCodeBytes[zipIndex++] = (byte)Integer.parseInt(s,2);}huffmanCodeBytes[huffmanCodeBytes.length - 1] = (byte)lastStringLength;return huffmanCodeBytes;}/***  5.对上述方法进行封装*/public byte[] zip(byte[] bytes){List<Node> nodes = getNodes(bytes);Node huffmanTree = createHuffmanTree(nodes);getHuffmanCode(huffmanTree,"",huffmanCodeBuilder);byte[] zip = huffmanCodeBytes(bytes, huffmanCode);return zip;}/***  1.解码 得到二进制的huffmanCode*/public String  getBinaryHuffmanCode(byte[] bytes){int length = bytes.length;StringBuilder sb = new StringBuilder();for (int i = 0; i < length - 1; i++) {int b = bytes[i];// 注意这里要int类型,因为下面要进行按位或操作String s = Integer.toBinaryString(b | 256);//                256 按位或 如果是正数 则倒数八位省略的零都能补上。//                          如果是负数 则倒数八位不会改变if(i != length - 2){String s2 = s.substring(s.length() - 8);sb.append(s2);}else{//                根据bytes[]最后一个记录最后一个字符串的长度来截取转换后的字符串。sb.append(s.substring(s.length() - bytes[length - 1]));}}return sb.toString();}/*** 2.根据huffmanCode还原原文*/public byte[] decode(HashMap<Byte,String> huffmanCode, String huffmanString){HashMap<String, Byte> hm = new HashMap<>();Set<Map.Entry<Byte, String>> entries = huffmanCode.entrySet();Iterator<Map.Entry<Byte, String>> iterator = entries.iterator();while (iterator.hasNext()) {Map.Entry<Byte, String> next =  iterator.next();Byte key = next.getKey();String value = next.getValue();hm.put(value,key);}
//        用来存储转换后的字节ArrayList<Byte> bytes = new ArrayList<>();int length = huffmanString.length();int end = 1;for (int i = 0; i < length; ) {String substring = huffmanString.substring(i, end);
//            if(hm.get(substring) == null){//                count++;
//            }else{//                bytes.add(hm.get(substring));
//                i = count;
//            }if(hm.get(substring) != null){bytes.add(hm.get(substring));i = end;}end++;}byte[] result = new byte[bytes.size()];for (int i = 0; i < result.length; i++) {result[i] = bytes.get(i);}return result;}/*** 3. 对上面两个方法进行封装*/public byte[] decompression(byte[] bytes,HashMap<Byte,String> huffmanCode){String huffmanString = getBinaryHuffmanCode(bytes);byte[] decode = decode(huffmanCode, huffmanString);return decode;}/***  对文件进行压缩*/public void compressionFile(String srcPath,String destPath){FileInputStream fis = null;byte[] bytes;ObjectOutputStream oos = null;FileOutputStream fos = null;try {fis = new FileInputStream(srcPath);int available = fis.available();bytes = new byte[available];
//            int content;fis.read(bytes);
//            for (int i = 0; (content = fis.read()) != -1; i++) {//                bytes[i] = (byte)content;
//            }/***  下面进行huffman编码*/byte[] zip = zip(bytes);fos = new FileOutputStream(destPath);oos = new ObjectOutputStream(fos);oos.writeObject(zip);oos.writeObject(huffmanCode);//            while((content = fis.read()) != -1){//                bytes.[]
//            }} catch (IOException e) {throw new RuntimeException(e);}finally{try {if(oos != null){oos.close();}if(fos != null){fos.close();}if(fis != null){fis.close();}} catch (IOException e) {throw new RuntimeException(e);}}}/***  对文件进行解压*/public void decompressionFile(String srcPath,String destPath){ObjectInputStream ois = null;FileOutputStream fos = null;FileInputStream fis = null;try {fis = new FileInputStream(srcPath);ois = new ObjectInputStream(fis);byte[] bytes = (byte[])ois.readObject();HashMap<Byte,String> hm = (HashMap<Byte,String>)ois.readObject();byte[] decompression = decompression(bytes, hm);fos = new FileOutputStream(destPath);fos.write(decompression);} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} finally{try{if(fos != null){fos.close();}if(ois != null){ois.close();}if(fis != null){fis.close();}}catch(IOException e){throw new RuntimeException(e);}}}
}

java huffman code 解压缩文件相关推荐

  1. Java中压缩/解压缩文件有什么好的解决方案呢?

    转入: Java中压缩/解压缩文件有什么好的解决方案呢? 下文笔者将讲述java中压缩/解压缩文件的处理方法分享,如下所示: 我们都知道,在java中JDK的Apache默认带有Zip库 但是它太大, ...

  2. 解压缩 JAVA手机_java解压缩文件

    {"data":{"id":"8000-000000437045-0","name":"SEO专题页栏目分发组 ...

  3. 哈夫曼编码解压缩文件 - Java实现

    文章目录 前言 一.文件压缩 二.文件解压 结语 前言 不了解哈夫曼树的可以移步查看我的另一篇博客:哈夫曼树(最优二叉树) 使用哈夫曼编码压缩文件,其实就是将每个字符的哈夫曼编码得到,每8位转为一个字 ...

  4. java流与文件——java生成解压缩文件(夹)

    [0]README 0.1) 本文描述转自 http://blog.csdn.net/chenssy/article/details/9622171 , 旨在理解 java流与文件--java生成解压 ...

  5. 基于Huffman编码的C语言解压缩文件程序

    #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>//极大 ...

  6. 基于Huffman算法的文件解压缩

    基于Huffman算法和LZ77算法的文件压缩(三) 基于Huffman算法和LZ77算法的文件压缩(一)和 基于Huffman算法和LZ77算法的文件压缩(二)讲解Huffman压缩的基本原理和文件 ...

  7. java使用tar算法压缩解压缩文件、数据流、byte[]字节数组

    全栈工程师开发手册 (作者:栾鹏) java教程全解 java使用tar算法压缩解压缩文件.数据流.byte[]字节数组 需要添加org.apache.commons.compress包,下载 测试代 ...

  8. java使用BZip算法压缩解压缩文件、数据流、byte[]字节数组

    全栈工程师开发手册 (作者:栾鹏) java教程全解 java使用BZip算法压缩解压缩文件.数据流.byte[]字节数组 需要添加org.apache.commons.compress包,下载 测试 ...

  9. java 上文件传示例_Java解压缩文件示例

    java 上文件传示例 Welcome to Java Unzip File Example. In the last post, we learned how to zip file and dir ...

最新文章

  1. 刚装oracle, 熟悉一下命令
  2. 节能电磁无线电导航信号放大电路 150kHz制版
  3. python教程书籍-初学者最好的Python书籍列表
  4. angular学习笔记(十九)-自定义指令修改dom
  5. Mangos源码分析(3):服务器结构探讨之简单的世界服实现
  6. 2019数据安装勾选_【安装部署】esweb服务器如何单独部署
  7. 【jQuery笔记】狂拍灰太狼案例笔记
  8. MySql.Data.dll官网下载
  9. python用二维码共享文档_[源码和文档分享]基于Python的QR二维码的生成与识别程序...
  10. 速修复!OpenSSL 披露DoS 和证书验证高危漏洞,可导致服务器崩溃
  11. wire routing 网格寻址
  12. mysql vs0215_0215 docker环境
  13. matlab计算电磁场程序,电磁场与波:电磁材料及MATLAB计算
  14. 详细总结卡尔曼滤波原理+具体案例分析
  15. PyQt5 打造GUI爬虫 小说下载器
  16. 二十年前割麦的童年(看哭了)
  17. Jmeter 修改背景色和字体
  18. 开发者道路上的季度考核及360环评----------囚徒困境
  19. 2021-2027全球与中国工业碳酸钠市场现状及未来发展趋势
  20. 欣海关务工作室原创文章——锦囊妙计(八) 对外承包工程

热门文章

  1. Python内置函数-min函数和max函数-详解
  2. echarts.min.js的引入
  3. 格式化日期——农历转换
  4. 动力电池测试项目概述
  5. Coursera连接不上的解决方法
  6. 红黑树结构原理的图文讲解(非代码)
  7. 最新!海康威视 java B/S SDK 强势登场
  8. 阿里云Aliware首批“铂金合作伙伴”花落谁家?——北京天源迪科当之无愧!!!...
  9. 【云原生|K8s系列第1篇】:K8s的基础概念、组件架构及实战安装
  10. opencv安装方法