Java压缩技术(六) BZIP2——Commons实现_茅坤宝骏氹的博客-程序员宅基地

技术标签: java 压缩技术  

转载自  Java压缩技术(六) BZIP2——Commons实现

BZip2与GZip有什么渊源,我这里不深究。我要说的只是,这两种算法,你在linux下都可以找到相应的操作命令。

GZip 
压缩 
gzip <file> 将得到压缩文件<file>.gz,同时删除文件<file> 
解压缩 
gzip -d <file>.gz 将得到压缩文件<file>,同时删除文件<file>.gz 

BZip2与之相当,几乎没有什么差别~~ 
BZip2 
压缩 
bzip2 <file> 将得到压缩文件<file>.bz2,同时删除文件<file> 
解压缩 
bzip2 -d <file>.bz2 将得到压缩文件<file>,同时删除文件<file>.bz2 
除了命令不同外,几乎是一样的!
再说实现。GZIP是JDK自带的算法实现,但BZip2则不曾享受这个待遇。不过,强大的Apache坚决不会让这些个在Linux下如鱼得水的算法在Java世界中销声匿迹。Apache在Commons Compress中提供了相应的实现。同时,还包括众所周知的tar、cpio、zip等算法实现,其中最为丰富的当属zip实现了!

我继续依葫芦画瓢~~~ 
BZip2CompressorOutputStream类用于压缩 
BZip2CompressorInputStream类用于解压缩 

先说压缩实现,BZip2CompressorOutputStream只有一个方法用于压缩,就是带定长的write方法。简单调用如下文所示: 

Java代码  
  1. /** 
  2.  * 数据压缩 
  3.  *  
  4.  * @param is 
  5.  * @param os 
  6.  * @throws Exception 
  7.  */  
  8. public static void compress(InputStream is, OutputStream os)  
  9.         throws Exception {  
  10.   
  11.     BZip2CompressorOutputStream gos = new BZip2CompressorOutputStream(os);  
  12.   
  13.     int count;  
  14.     byte data[] = new byte[BUFFER];  
  15.     while ((count = is.read(data, 0, BUFFER)) != -1) {  
  16.         gos.write(data, 0, count);  
  17.     }  
  18.   
  19.     gos.finish();  
  20.   
  21.     gos.flush();  
  22.     gos.close();  
  23. }  

与GZip实现有何差别?除了换掉了GZIPOutputStream没有任何差别。
解压缩就更不用说了,BZip2CompressorInputStream提供了一个带定长的read方法。简单调用如下文所示: 
Java代码
  1. /** 
  2.  * 数据解压缩 
  3.  *  
  4.  * @param is 
  5.  * @param os 
  6.  * @throws Exception 
  7.  */  
  8. public static void decompress(InputStream is, OutputStream os)  
  9.         throws Exception {  
  10.   
  11.     BZip2CompressorInputStream gis = new BZip2CompressorInputStream(is);  
  12.   
  13.     int count;  
  14.     byte data[] = new byte[BUFFER];  
  15.     while ((count = gis.read(data, 0, BUFFER)) != -1) {  
  16.         os.write(data, 0, count);  
  17.     }  
  18.   
  19.     gis.close();  
  20. }  

嗯,没什么难度! IT这行就是这样,只要你肯用心,能触类旁通,就能融会贯通!
给一个完整实现: 
Java代码
  1. /** 
  2.  * 2010-4-15 
  3.  */  
  4. package org.zlex.commons.compress.compress;  
  5.   
  6. import java.io.ByteArrayInputStream;  
  7. import java.io.ByteArrayOutputStream;  
  8. import java.io.File;  
  9. import java.io.FileInputStream;  
  10. import java.io.FileOutputStream;  
  11. import java.io.InputStream;  
  12. import java.io.OutputStream;  
  13.   
  14. import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;  
  15. import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;  
  16.   
  17. /** 
  18.  * BZip2工具 
  19.  *  
  20.  * @author  <a href="mailto:[email protected]">梁栋</a> 
  21.  * @since 1.0 
  22.  */  
  23. public abstract class BZip2Utils {  
  24.   
  25.     public static final int BUFFER = 1024;  
  26.     public static final CharSequence EXT = ".bz2";  
  27.   
  28.     /** 
  29.      * 数据压缩 
  30.      *  
  31.      * @param data 
  32.      * @return 
  33.      * @throws Exception 
  34.      */  
  35.     public static byte[] compress(byte[] data) throws Exception {  
  36.         ByteArrayInputStream bais = new ByteArrayInputStream(data);  
  37.         ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  38.   
  39.         // 压缩  
  40.         compress(bais, baos);  
  41.   
  42.         byte[] output = baos.toByteArray();  
  43.   
  44.         baos.flush();  
  45.         baos.close();  
  46.   
  47.         bais.close();  
  48.   
  49.         return output;  
  50.     }  
  51.   
  52.     /** 
  53.      * 文件压缩 
  54.      *  
  55.      * @param file 
  56.      * @throws Exception 
  57.      */  
  58.     public static void compress(File file) throws Exception {  
  59.         compress(file, true);  
  60.     }  
  61.   
  62.     /** 
  63.      * 文件压缩 
  64.      *  
  65.      * @param file 
  66.      * @param delete 
  67.      *            是否删除原始文件 
  68.      * @throws Exception 
  69.      */  
  70.     public static void compress(File file, boolean delete) throws Exception {  
  71.         FileInputStream fis = new FileInputStream(file);  
  72.         FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);  
  73.   
  74.         compress(fis, fos);  
  75.   
  76.         fis.close();  
  77.         fos.flush();  
  78.         fos.close();  
  79.   
  80.         if (delete) {  
  81.             file.delete();  
  82.         }  
  83.     }  
  84.   
  85.     /** 
  86.      * 数据压缩 
  87.      *  
  88.      * @param is 
  89.      * @param os 
  90.      * @throws Exception 
  91.      */  
  92.     public static void compress(InputStream is, OutputStream os)  
  93.             throws Exception {  
  94.   
  95.         BZip2CompressorOutputStream gos = new BZip2CompressorOutputStream(os);  
  96.   
  97.         int count;  
  98.         byte data[] = new byte[BUFFER];  
  99.         while ((count = is.read(data, 0, BUFFER)) != -1) {  
  100.             gos.write(data, 0, count);  
  101.         }  
  102.   
  103.         gos.finish();  
  104.   
  105.         gos.flush();  
  106.         gos.close();  
  107.     }  
  108.   
  109.     /** 
  110.      * 文件压缩 
  111.      *  
  112.      * @param path 
  113.      * @throws Exception 
  114.      */  
  115.     public static void compress(String path) throws Exception {  
  116.         compress(path, true);  
  117.     }  
  118.   
  119.     /** 
  120.      * 文件压缩 
  121.      *  
  122.      * @param path 
  123.      * @param delete 
  124.      *            是否删除原始文件 
  125.      * @throws Exception 
  126.      */  
  127.     public static void compress(String path, boolean delete) throws Exception {  
  128.         File file = new File(path);  
  129.         compress(file, delete);  
  130.     }  
  131.   
  132.     /** 
  133.      * 数据解压缩 
  134.      *  
  135.      * @param data 
  136.      * @return 
  137.      * @throws Exception 
  138.      */  
  139.     public static byte[] decompress(byte[] data) throws Exception {  
  140.         ByteArrayInputStream bais = new ByteArrayInputStream(data);  
  141.         ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  142.   
  143.         // 解压缩  
  144.   
  145.         decompress(bais, baos);  
  146.   
  147.         data = baos.toByteArray();  
  148.   
  149.         baos.flush();  
  150.         baos.close();  
  151.   
  152.         bais.close();  
  153.   
  154.         return data;  
  155.     }  
  156.   
  157.     /** 
  158.      * 文件解压缩 
  159.      *  
  160.      * @param file 
  161.      * @throws Exception 
  162.      */  
  163.     public static void decompress(File file) throws Exception {  
  164.         decompress(file, true);  
  165.     }  
  166.   
  167.     /** 
  168.      * 文件解压缩 
  169.      *  
  170.      * @param file 
  171.      * @param delete 
  172.      *            是否删除原始文件 
  173.      * @throws Exception 
  174.      */  
  175.     public static void decompress(File file, boolean delete) throws Exception {  
  176.         FileInputStream fis = new FileInputStream(file);  
  177.         FileOutputStream fos = new FileOutputStream(file.getPath().replace(EXT,  
  178.                 ""));  
  179.         decompress(fis, fos);  
  180.         fis.close();  
  181.         fos.flush();  
  182.         fos.close();  
  183.   
  184.         if (delete) {  
  185.             file.delete();  
  186.         }  
  187.     }  
  188.   
  189.     /** 
  190.      * 数据解压缩 
  191.      *  
  192.      * @param is 
  193.      * @param os 
  194.      * @throws Exception 
  195.      */  
  196.     public static void decompress(InputStream is, OutputStream os)  
  197.             throws Exception {  
  198.   
  199.         BZip2CompressorInputStream gis = new BZip2CompressorInputStream(is);  
  200.   
  201.         int count;  
  202.         byte data[] = new byte[BUFFER];  
  203.         while ((count = gis.read(data, 0, BUFFER)) != -1) {  
  204.             os.write(data, 0, count);  
  205.         }  
  206.   
  207.         gis.close();  
  208.     }  
  209.   
  210.     /** 
  211.      * 文件解压缩 
  212.      *  
  213.      * @param path 
  214.      * @throws Exception 
  215.      */  
  216.     public static void decompress(String path) throws Exception {  
  217.         decompress(path, true);  
  218.     }  
  219.   
  220.     /** 
  221.      * 文件解压缩 
  222.      *  
  223.      * @param path 
  224.      * @param delete 
  225.      *            是否删除原始文件 
  226.      * @throws Exception 
  227.      */  
  228.     public static void decompress(String path, boolean delete) throws Exception {  
  229.         File file = new File(path);  
  230.         decompress(file, delete);  
  231.     }  
  232.   
  233. }  

对应再来个测试用例,测试用例如下所示: 
Java代码 
  1. /** 
  2.  * 2010-4-13 
  3.  */  
  4. package org.zlex.commons.compress.compress;  
  5.   
  6. import static org.junit.Assert.assertEquals;  
  7.   
  8. import java.io.DataInputStream;  
  9. import java.io.File;  
  10. import java.io.FileInputStream;  
  11. import java.io.FileOutputStream;  
  12.   
  13. import org.junit.Test;  
  14.   
  15. /** 
  16.  * BZip2 
  17.  *  
  18.  * @author <a href="mailto:[email protected]">梁栋</a> 
  19.  * @since 1.0 
  20.  */  
  21. public class BZip2UtilsTest {  
  22.   
  23.     private String inputStr = "[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],zlex.snowol[email protected],[email protected],[email protected],[email protected]";  
  24.   
  25.     @Test  
  26.     public final void testDataCompress() throws Exception {  
  27.   
  28.         byte[] input = inputStr.getBytes();  
  29.         System.err.println("原文:\t" + inputStr);  
  30.         System.err.println("长度:\t" + input.length);  
  31.   
  32.         byte[] data = BZip2Utils.compress(input);  
  33.         System.err.println("压缩后:\t");  
  34.         System.err.println("长度:\t" + data.length);  
  35.   
  36.         byte[] output = BZip2Utils.decompress(data);  
  37.         String outputStr = new String(output);  
  38.         System.err.println("解压缩后:\t" + outputStr);  
  39.         System.err.println("长度:\t" + output.length);  
  40.   
  41.         assertEquals(inputStr, outputStr);  
  42.   
  43.     }  
  44.   
  45.     @Test  
  46.     public final void testFileCompress() throws Exception {  
  47.   
  48.         FileOutputStream fos = new FileOutputStream("d:/f.txt");  
  49.   
  50.         fos.write(inputStr.getBytes());  
  51.         fos.flush();  
  52.         fos.close();  
  53.   
  54.         BZip2Utils.compress("d:/f.txt");  
  55.   
  56.         BZip2Utils.decompress("d:/f.txt.bz2");  
  57.   
  58.         File file = new File("d:/f.txt");  
  59.   
  60.         FileInputStream fis = new FileInputStream(file);  
  61.   
  62.         DataInputStream dis = new DataInputStream(fis);  
  63.   
  64.         byte[] data = new byte[(int) file.length()];  
  65.         dis.readFully(data);  
  66.   
  67.         fis.close();  
  68.   
  69.         String outputStr = new String(data);  
  70.         assertEquals(inputStr, outputStr);  
  71.     }  
  72. }  

虽然,两种算法在代码实现上几乎没有什么差别,但在压缩上想要看到效果,还真让我费了点事!
控制台输出如下所示: 
引用

529字节-->76字节! 
GZIP本身不需要太长的内容,经过压缩就能体现出压缩效果,而BZip2则需要压缩很长的内容时,才能体现其压缩效果,这说明BZip2更适合大数据压缩?!

Commons Compress不仅支持BZip2算法实现,同时也支持GZip算法实现。对于GZip算法实现,与Java原生实现基本上没有什么差别。其源代码分析,仅仅是做了简单的包装。 
不过有必要提及的一点是,Commons Compress为压缩(GZip和BZip2)构建了压缩算法工厂类 CompressorStreamFactory 。通过这个类可以方便的构建GZip和BZip2的输入输出流,关键字分别为“gz”和“bzip2”。 
GZip 
Java代码 
  1. // GzipCompressorInputStream        
  2. CompressorInputStream gzipIn = new CompressorStreamFactory()  
  3.         .createCompressorInputStream("gz", is);  
  4.   
  5. // GzipCompressorOutputStream  
  6. CompressorOutputStream gzipOut = new CompressorStreamFactory()  
  7.         .createCompressorOutputStream("gz", os);  

BZip2 
Java代码 
  1. // BZip2CompressorInputStream  
  2. CompressorInputStream bzip2In = new CompressorStreamFactory()  
  3.         .createCompressorInputStream("bzip2", is);  
  4.   
  5. // BZip2CompressorOutputStream  
  6. CompressorOutputStream bzip2Out = new CompressorStreamFactory()  
  7.         .createCompressorOutputStream("bzip2", os);  
GZip和BZip2在算法实现步骤上基本上没有什么差别,如果有必要统一,可按上述代码实现!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/moakun/article/details/80639402

智能推荐

高精度系列汇总(大数加、减、乘、除)_Brightess的博客-程序员宅基地

AcWing 791. 高精度加法(高精度+高精度)给定两个正整数,计算它们的和。输入格式共两行,每行包含一个整数。输出格式共一行,包含所求的和。数据范围1≤整数长度≤100000输入样例:1223输出样例:35#include<iostream>#include<string>#include<vector>using namespace std;vector<int> add(vector<int>&

Java依据文件头获取文件类型_java 文件流返回如何用请求头获取文件格式_buster2014的博客-程序员宅基地

http://blog.csdn.net/diquren/article/details/49763781java根据文件头获取文件类型 文件头是位于文件开头的一段承担一定任务的数据,一般都在开头的部分。头文件作为一种包含功能函数、数据接口声明的载体文件,用于保存程序的声明(declaration),而定义文件用于保存程序的实现 (implementation)。_java 文件流返回如何用请求头获取文件格式

Vue.js 踩坑记 (二)_lee576的博客-程序员宅基地

上次用npm命令安装时发现下载速度特别慢,后来找到原因,原来npm是国外的网络,国内淘宝提供了一个镜像,叫cnpm,速度要快很多首先安装它 npm install -g cnpm --registry=https://registry.npm.taobao.org然后我们使用Vue.js 开发项目还需要安装一个 vue cli,这是vue 项目的模板框架。这个时候就可以用 cnpm 来安装了,速度...

linux脚本交互输入,Shell 交互输入自动化_Sourav Goswami的博客-程序员宅基地

Shell 交互输入自动化,我们知道命令可以接受命令行参数。Linux也支持很多交互式应用程序,如passwd和ssh。我们可以创建自己的交互式shell脚本。对于普通用户而言,相较于记忆命令行参数及其正确的顺序,同一系列提示信息打交道要更容易。例如,一个备份用户工作成果的脚本看起来应该像这样:如果你需要返回到同一交互式应用,实现交互式应用自动化能够节省大量的时间;如果你正在开发此类应用,这也可以..._linux 交互式程序入参 <

python生日祝福短信_python自动发送生日祝福邮件-程序员宅基地

最近刚开学,班里的事也挺多,大多都涉及到excel的使用。本来我excel用得不是很熟,很多高级的操作都不会。比如给两列的交赋值等。在网上搜了下,发现这些操作的实现都涉及到excel内部的一些命令,而不是简单的鼠标操作。Oh NO!这一套规范又不知得学到什么时候了。所以,一直在想有没有别办法。记得python能操作excel,似乎可以用python写个脚本啥的。正好,昨天用excel查信息时,发现..._python+execl 发送生日祝福邮件

HADOOP添加第三方jar依赖_hadoop jar 运行mapreduce指定第三方依赖jar_没有格子衬衫的程序员的博客-程序员宅基地

每次运行hadoop jar命令时,会重新设置HADOOP_CLASS这个环境变量,并将这个变量的值赋给CLASSPATH,所以,只能通过设置HADOOP_CLASS这个环境变量来添加第三方的依赖,而设置CLASSPATH并不会生效。在MR任务在提交阶段和task运行阶段,主要会遇见两类依赖问题:依赖找不到和依赖冲突。提交阶段:1. 依赖找不到 通常两种解决方案将第三方j..._hadoop jar 运行mapreduce指定第三方依赖jar

随便推点

K-Means聚类算法原理及其优化_大数据分析 聚类优化_AI路上的小白的博客-程序员宅基地

K-Means算法是无监督的聚类算法,它实现起来比较简单,聚类效果也不错,因此应用很广泛。K-Means算法有大量的变体,本文就从最传统的K-Means算法讲起,在其基础上讲述K-Means的优化变体方法。包括初始化优化K-Means++, 距离计算优化elkan K-Means算法和大数据情况下的优化Mini Batch K-Means算法。1. K-Means原理初探K-Means算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间_大数据分析 聚类优化

黑马:STL案例:评委打分(210)_黑马案例 评委打分_至臻卡比兽的博客-程序员宅基地

案例描述:有五名选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除评委中最低分,取平均分。实现步骤:1.创建五名选手,放到vector中2.遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque容器中3.sort算法对deque容器中分数排序,去除最高分和最低分4.deque容器遍历一遍,累加总分5.获取平均分#include<iostream>using namespace std;#include_黑马案例 评委打分

pcduino上编译安装ros_分wet包和dry包_jing35030401的博客-程序员宅基地

原来用别人的博客写的,现在全搬过来参考:1 ros官网的arm安装包安装:http://wiki.ros.org/groovy/Installation/UbuntuARM2源代码编译安装: http://wiki.ros.org/groovy/Installation/Source3 http://wiki.ros.org/groovy/Installation/Lina_分wet包和dry包

matlab颜色直方图特征提取,灰度直方图特征提取的Matlab实现_郜婕的博客-程序员宅基地

Computer Knowledge and Technology 电脑知识与技术第5卷第32期(2009年11月)本栏目责任编辑:唐一东人工智能及识别技术灰度直方图特征提取的Matlab 实现刘益新1,郭依正2(1.金山职业技术学院计算机系,江苏扬中212200;2.南京师范大学泰州学院信息科学与技术系,江苏泰州225300)摘要:图像特征提取是图像识别、图像数据挖掘、基于内容的图像检索等的基础..._灰度直方图特征提取

css属性align-content与align-items的区别_css align-items和align-content-程序员宅基地

页面结构:<body> <div id="condiv"> <div class="row1 subdiv"></div> <div class="row2 subdiv"></div> <div class="row3 subdiv"></div> <div class="row4 subdiv"></div>_css align-items和align-content

learning about Project Management -A04- Project Team_山书生的博客-程序员宅基地

所有的项目,都离不开一个贴切的团队!为什么说贴切呢,这是因为“人员+团队”对于项目的成功有很大的干系! 作为呈上启下之产物——团队组建,在项目计划里,是一个重要关键点。在接下来的项目需求分析、开发/实施、测试等方方面面,这些人员是必须明确任务、明确职责、分工合作的! 团队的组建,一般依据项目属性、任务内容、投入预算、时间期限等各方面来进行人员角色、人员数量的规划。

推荐文章

热门文章

相关标签