使用霍夫曼编码进行字符串和文件的压缩和解压实验
解压文件时出现错误 未解决
package huffmancoding;
import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;
import sun.misc.OSEnvironment;
import java.io.*;
import java.util.*;
/**
* 将字符串保存为Huffman编码
* huffman编码是以霍夫曼树为基础的可变字长的前缀编码,也可以进行文件的无损压缩,压缩率在20% -- 90% 之间
* 可变字长编码: 不遵循字符与二进制代码间的一一对应的转换关系,而是统计每个字符出现的次数后根据权重生成霍夫曼树
* 然后根据不同字符的不同路径,生成不同的字符对应的二进制代码,可节省传输空间
* 前缀编码: 同一组编码中每个字符的编码不为其他字符编码的编码头
*
*/
public class HuffmanCoding {
private static Map<Byte , String> huffmanMap = new HashMap<>(); //保存生成的霍夫曼编码表
private static StringBuilder str = new StringBuilder();
// private static String str1 = null; 验证转换前后字符串是否相等使用
public static void main(String[] args) {
/* String content = "I like like like java do you like a java";
byte[] contentBytes = content.getBytes();*/
// System.out.println("字符串包含的字符个数为: " + contentBytes.length);
// //统计byte数组每个字符的个数,并将其保存为node结点,放入list集合中
// List<Node> nodeList = getNodeList(contentBytes);
// System.out.println("结点集合为: " + nodeList);
// //由结点集合生成霍夫曼树
// Node root = createHuffmanTree(nodeList);
// System.out.println("生成的霍夫曼树为:-----------");
// preOrder(root);
// Map<Byte, String> huffmanMap = getHuffmanMap(root);
// System.out.println("生成的霍夫曼编码表为:~~~~~~~~~~~~~~~~");
// System.out.println(huffmanMap);
// byte[] bytes = zip(contentBytes);
// System.out.println("字节数组长度为: " + bytes.length);
// System.out.println("转换后的字节数组为");
// System.out.println(Arrays.toString(bytes));
/*byte[] huffmanCodeBytes = getHuffmanCodeBytes(contentBytes);
System.out.println("字节数组长度为: " + huffmanCodeBytes.length);
System.out.println("转换后的字节数组为");
System.out.println(Arrays.toString(huffmanCodeBytes));
byte[] result = deCode(huffmanMap, huffmanCodeBytes);
String s = new String(result);
// System.out.println(s.equals(str1)); 验证转换前后字符串是否相等使用
System.out.println(s);*/
// zipFile("D:\\123.jpg" , "D:\\123.zip");
// System.out.println("压缩success");
unZipFile("D:\\123.zip" , "D:\\321.jpg");
System.out.println("解压success");
}
//解压文件
public static void unZipFile(String srcFile , String desFile){
FileInputStream fis = null;
FileOutputStream fos = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(srcFile);
ois = new ObjectInputStream(fis);
//得到压缩后的数据
byte[] huffmanBytes = (byte[]) ois.readObject();
//得到编码表
Map<Byte , String> tempHuffmanMap = (Map<Byte , String>) ois.readObject();
//解码
byte[] bytes = deCode(tempHuffmanMap, huffmanBytes);
//写出文件
fos = new FileOutputStream(desFile);
fos.write(bytes);
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(fis != null){
fis.close();
}
if(fos != null){
fos.close();
}
if(ois != null){
ois.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
//使用霍夫曼编码进行文件压缩
//不适用条件:1、ppt、视频等已经经过压缩的文件 2、较复杂的图片等没有压缩空间的文件
public static void zipFile(String srcFile , String desFile){
FileInputStream fis = null;
FileOutputStream fos