java huffman code 解压缩文件
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 解压缩文件相关推荐
- Java中压缩/解压缩文件有什么好的解决方案呢?
转入: Java中压缩/解压缩文件有什么好的解决方案呢? 下文笔者将讲述java中压缩/解压缩文件的处理方法分享,如下所示: 我们都知道,在java中JDK的Apache默认带有Zip库 但是它太大, ...
- 解压缩 JAVA手机_java解压缩文件
{"data":{"id":"8000-000000437045-0","name":"SEO专题页栏目分发组 ...
- 哈夫曼编码解压缩文件 - Java实现
文章目录 前言 一.文件压缩 二.文件解压 结语 前言 不了解哈夫曼树的可以移步查看我的另一篇博客:哈夫曼树(最优二叉树) 使用哈夫曼编码压缩文件,其实就是将每个字符的哈夫曼编码得到,每8位转为一个字 ...
- java流与文件——java生成解压缩文件(夹)
[0]README 0.1) 本文描述转自 http://blog.csdn.net/chenssy/article/details/9622171 , 旨在理解 java流与文件--java生成解压 ...
- 基于Huffman编码的C语言解压缩文件程序
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>//极大 ...
- 基于Huffman算法的文件解压缩
基于Huffman算法和LZ77算法的文件压缩(三) 基于Huffman算法和LZ77算法的文件压缩(一)和 基于Huffman算法和LZ77算法的文件压缩(二)讲解Huffman压缩的基本原理和文件 ...
- java使用tar算法压缩解压缩文件、数据流、byte[]字节数组
全栈工程师开发手册 (作者:栾鹏) java教程全解 java使用tar算法压缩解压缩文件.数据流.byte[]字节数组 需要添加org.apache.commons.compress包,下载 测试代 ...
- java使用BZip算法压缩解压缩文件、数据流、byte[]字节数组
全栈工程师开发手册 (作者:栾鹏) java教程全解 java使用BZip算法压缩解压缩文件.数据流.byte[]字节数组 需要添加org.apache.commons.compress包,下载 测试 ...
- java 上文件传示例_Java解压缩文件示例
java 上文件传示例 Welcome to Java Unzip File Example. In the last post, we learned how to zip file and dir ...
最新文章
- 刚装oracle, 熟悉一下命令
- 节能电磁无线电导航信号放大电路 150kHz制版
- python教程书籍-初学者最好的Python书籍列表
- angular学习笔记(十九)-自定义指令修改dom
- Mangos源码分析(3):服务器结构探讨之简单的世界服实现
- 2019数据安装勾选_【安装部署】esweb服务器如何单独部署
- 【jQuery笔记】狂拍灰太狼案例笔记
- MySql.Data.dll官网下载
- python用二维码共享文档_[源码和文档分享]基于Python的QR二维码的生成与识别程序...
- 速修复!OpenSSL 披露DoS 和证书验证高危漏洞,可导致服务器崩溃
- wire routing 网格寻址
- mysql vs0215_0215 docker环境
- matlab计算电磁场程序,电磁场与波:电磁材料及MATLAB计算
- 详细总结卡尔曼滤波原理+具体案例分析
- PyQt5 打造GUI爬虫 小说下载器
- 二十年前割麦的童年(看哭了)
- Jmeter 修改背景色和字体
- 开发者道路上的季度考核及360环评----------囚徒困境
- 2021-2027全球与中国工业碳酸钠市场现状及未来发展趋势
- 欣海关务工作室原创文章——锦囊妙计(八) 对外承包工程