前面我们学习了赫夫曼的编码和解码的过程,我们操作的对象是一串字符串,而实质上赫夫曼的压缩和解压的过程不仅仅只针对于字符串的处理,而且文件也是可以的,如图片的压缩和解压,关于文件的压缩和解压我们本节来讲,我们来看看实际的案例.
文件压缩要求
假设给我们一张图片文件,要求我们进行无所压缩处理,由于我们之前做了很多前提工作,这里我们直接写代码实现即可
代码实现过程:
当然我们会利用前面一些公共的方法,这里就不在重复了,直接看代码:
/**
*
* @param srcFilePath 带压缩文件的全路径
* @param desFilePath 压缩过后的文件路径
*/
public static void zipFile(String srcFilePath,String desFilePath){
//1.创建文件的输入流来读取我们的文件
FileInputStream inputStream = null;
//2.创建输出流
FileOutputStream outputStream = null;
//3.创建ObjectOutputStream来关联我们的FileOutputStream
ObjectOutputStream objectOutputStream = null;
//创建一个和源文件大小一样的byte数组来存储我们读取的数据
byte[] b = null;
try {
inputStream = new FileInputStream(srcFilePath);
b = new byte[inputStream.available()];
//读取file的内容到b数组中
inputStream.read(b);
//对源文件压缩
byte[] huffmanByte = huffmanZip(b);
//存放我们的压缩文件
outputStream = new FileOutputStream(desFilePath);
//关联文件文件输出流
objectOutputStream = new ObjectOutputStream(outputStream);
//将赫夫曼编码过后的字节数组写入(以object的形式)压缩文件
objectOutputStream.writeObject(huffmanByte);
//同样也把赫夫曼编码写入压缩文件
objectOutputStream.writeObject(huffmanCodes);
}catch (Exception e){
e.printStackTrace();
}finally {
try {
inputStream.close();
objectOutputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
因为是文件的处理这里涉及到了io流的操作.巧妙的是我们这里利用的是对象流(ObjectOutputStream)来处理,为什么会利用对象流这是为了后面解压的时候方便而考虑到的,不知道效果如何我们测试一把,测试代码如下:
System.out.println("压缩文件测试~~~");
String srcPath = "d://完整流程.png";
String desPath = "d://完整流程.zip";
zipFile(srcPath,desPath);
System.out.println("压缩完毕----------")
图片压缩测试结果图.png来看测试结果如下图所示:
注意这个压缩完成之后不能用我们的常规解压工具开进行解压操作,需要我们自己来编写解压的算法来完成解压过程,上图我们发现解压的操作已经完成,那么我们先来总结下上述的思路流程:
思路分析
从代码的编写我们发现大致的思路是这样的
- 首先我们读取源文件到一个字节数组中
- 通过赫夫曼编码处理得到赫夫曼编码表
- 最后完成压缩
看完了压缩过程,我们直接来看解压过程
/**
*
* @param zipSrcPath 待解压的文件路径
* @param descFilePath 解压后文件所放的位置
*/
public static void decodeFile(String zipSrcPath,String descFilePath){
//定义文件输入流
InputStream inputStream = null;
//定义对象输入流
ObjectInputStream objectInputStream = null;
//定义文件的输出流
OutputStream outputStream = null;
try {
//常见文件输入流
inputStream = new FileInputStream(zipSrcPath);
//创建一个和inputStream的对象输入流
objectInputStream = new ObjectInputStream(inputStream);
//读取byte数组中的赫夫曼编码huffmanBytes
byte[] huffmanBytes = (byte[])objectInputStream.readObject();
//读取赫夫曼编码表huffmanCodes
Map<Byte,String> huffmanCodes = (Map<Byte, String>)objectInputStream.readObject();
//解压
byte[] bytes = decode(huffmanCodes, huffmanBytes);
//将bytes写入到目的地址
outputStream = new FileOutputStream(descFilePath);
//将数据写入到descFilePath中
outputStream.write(bytes);
}catch (Exception e){
e.printStackTrace();
}finally {
try {
outputStream.close();
objectInputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里就不在啰嗦了,直接看测试代码:
String srcPath = "d://完整流程.zip";
String descPath = "d://完整流程2.png";
decodeFile(srcPath,descPath);
System.out.println("解压完成!");
文件解压测试结果图.png来看测试结果:
最后解压发现跟原文件是一致的,亲测有效,图片打开没有受损,那么关于赫夫曼所有的学习到这就算结束了,完整代码请在git上看:
网友评论