java 压缩技术,Java压缩技术(四) GZIP——Java原生实现

趁着头脑清楚,抓紧时间继续整理!

a6558229767b87df3caca2cbd544f611.gif

熟悉linux的朋友可能都用过文件压缩命令,譬如最为简单的gzip命令。

相关链接:

Java压缩技术(一) ZLib

Java压缩技术(二) ZIP压缩——Java原生实现

Java压缩技术(三) ZIP解压缩——Java原生实现

Java压缩技术(四) GZIP——Java原生实现

Java压缩技术(五) GZIP相关——浏览器解析

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

Java压缩技术(七) TAR——Commons实现

GZIP常常用在linxu环境下,是一种非常简单的压缩算法。在Java实现API中,它仅仅包含两个实现类:GZIPInputStream和GZIPOutputStream。

GZIPOutputStream类用于压缩

GZIPInputStream类用于解压缩

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

Java代码

0fd15f644694a335690493798a0b6d72.png

/**

*数据压缩

*

*@paramis

*@paramos

*@throwsException

*/

publicstaticvoidcompress(InputStreamis,OutputStreamos)

throwsException{

GZIPOutputStreamgos=newGZIPOutputStream(os);

intcount;

bytedata[]=newbyte[BUFFER];

while((count=is.read(data,0,BUFFER))!=-1){

gos.write(data,0,count);

}

gos.finish();

gos.flush();

gos.close();

}

记得完成操作后,调用finish方法和flush方法!

a6558229767b87df3caca2cbd544f611.gif

核心的压缩实现就这么多!

a6558229767b87df3caca2cbd544f611.gif

对于解压缩,GZIPInputStream也对应GZIPOutputStream提供了一个带定长的read方法。简单调用如下文所示:

Java代码

0fd15f644694a335690493798a0b6d72.png

/**

*数据解压缩

*

*@paramis

*@paramos

*@throwsException

*/

publicstaticvoiddecompress(InputStreamis,OutputStreamos)

throwsException{

GZIPInputStreamgis=newGZIPInputStream(is);

intcount;

bytedata[]=newbyte[BUFFER];

while((count=gis.read(data,0,BUFFER))!=-1){

os.write(data,0,count);

}

gis.close();

}

就这么简单!

a6558229767b87df3caca2cbd544f611.gif核心内容完毕!

顺便补充一下,在liunx下操作gzip命令

gzip file用于压缩,如gzip

a.txt将得到文件a.txt.gz,同时删除文件a.txt!。

gzip -d file.gz用于解压缩,如gzip

-d a.txt.gz将得到文件a.txt,同时删除文件a.txt.gz!。

根据这些特性,我补充了相应的文件操作实现,详见下文!

a6558229767b87df3caca2cbd544f611.gif

完整实现:

Java代码

0fd15f644694a335690493798a0b6d72.png

/**

*2010-4-13

*/

packageorg.zlex.commons.io;

importjava.io.ByteArrayInputStream;

importjava.io.ByteArrayOutputStream;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileOutputStream;

importjava.io.InputStream;

importjava.io.OutputStream;

importjava.util.zip.GZIPInputStream;

importjava.util.zip.GZIPOutputStream;

/**

*GZIP工具

*

*@author梁栋

*@since1.0

*/

publicabstractclassGZipUtils{

publicstaticfinalintBUFFER=1024;

publicstaticfinalStringEXT=".gz";

/**

*数据压缩

*

*@paramdata

*@return

*@throwsException

*/

publicstaticbyte[]compress(byte[]data)throwsException{

ByteArrayInputStreambais=newByteArrayInputStream(data);

ByteArrayOutputStreambaos=newByteArrayOutputStream();

//压缩

compress(bais,baos);

byte[]output=baos.toByteArray();

baos.flush();

baos.close();

bais.close();

returnoutput;

}

/**

*文件压缩

*

*@paramfile

*@throwsException

*/

publicstaticvoidcompress(Filefile)throwsException{

compress(file,true);

}

/**

*文件压缩

*

*@paramfile

*@paramdelete

*是否删除原始文件

*@throwsException

*/

publicstaticvoidcompress(Filefile,booleandelete)throwsException{

FileInputStreamfis=newFileInputStream(file);

FileOutputStreamfos=newFileOutputStream(file.getPath()+EXT);

compress(fis,fos);

fis.close();

fos.flush();

fos.close();

if(delete){

file.delete();

}

}

/**

*数据压缩

*

*@paramis

*@paramos

*@throwsException

*/

publicstaticvoidcompress(InputStreamis,OutputStreamos)

throwsException{

GZIPOutputStreamgos=newGZIPOutputStream(os);

intcount;

bytedata[]=newbyte[BUFFER];

while((count=is.read(data,0,BUFFER))!=-1){

gos.write(data,0,count);

}

gos.finish();

gos.flush();

gos.close();

}

/**

*文件压缩

*

*@parampath

*@throwsException

*/

publicstaticvoidcompress(Stringpath)throwsException{

compress(path,true);

}

/**

*文件压缩

*

*@parampath

*@paramdelete

*是否删除原始文件

*@throwsException

*/

publicstaticvoidcompress(Stringpath,booleandelete)throwsException{

Filefile=newFile(path);

compress(file,delete);

}

/**

*数据解压缩

*

*@paramdata

*@return

*@throwsException

*/

publicstaticbyte[]decompress(byte[]data)throwsException{

ByteArrayInputStreambais=newByteArrayInputStream(data);

ByteArrayOutputStreambaos=newByteArrayOutputStream();

//解压缩

decompress(bais,baos);

data=baos.toByteArray();

baos.flush();

baos.close();

bais.close();

returndata;

}

/**

*文件解压缩

*

*@paramfile

*@throwsException

*/

publicstaticvoiddecompress(Filefile)throwsException{

decompress(file,true);

}

/**

*文件解压缩

*

*@paramfile

*@paramdelete

*是否删除原始文件

*@throwsException

*/

publicstaticvoiddecompress(Filefile,booleandelete)throwsException{

FileInputStreamfis=newFileInputStream(file);

FileOutputStreamfos=newFileOutputStream(file.getPath().replace(EXT,

""));

decompress(fis,fos);

fis.close();

fos.flush();

fos.close();

if(delete){

file.delete();

}

}

/**

*数据解压缩

*

*@paramis

*@paramos

*@throwsException

*/

publicstaticvoiddecompress(InputStreamis,OutputStreamos)

throwsException{

GZIPInputStreamgis=newGZIPInputStream(is);

intcount;

bytedata[]=newbyte[BUFFER];

while((count=gis.read(data,0,BUFFER))!=-1){

os.write(data,0,count);

}

gis.close();

}

/**

*文件解压缩

*

*@parampath

*@throwsException

*/

publicstaticvoiddecompress(Stringpath)throwsException{

decompress(path,true);

}

/**

*文件解压缩

*

*@parampath

*@paramdelete

*是否删除原始文件

*@throwsException

*/

publicstaticvoiddecompress(Stringpath,booleandelete)throwsException{

Filefile=newFile(path);

decompress(file,delete);

}

}

罗嗦了半天,到底行不行?

来个测试用例,测试用例如下所示:

Java代码

0fd15f644694a335690493798a0b6d72.png

/**

*2010-4-13

*/

packageorg.zlex.commons.compress.compress;

importstaticorg.junit.Assert.assertEquals;

importjava.io.DataInputStream;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileOutputStream;

importorg.junit.Test;

/**

*@author梁栋

*@since1.0

*/

publicclassGZipUtilsTest{

privateStringinputStr="zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org";

@Test

publicfinalvoidtestDataCompress()throwsException{

System.err.println("原文:\t"+inputStr);

byte[]input=inputStr.getBytes();

System.err.println("长度:\t"+input.length);

byte[]data=GZipUtils.compress(input);

System.err.println("压缩后:\t");

System.err.println("长度:\t"+data.length);

byte[]output=GZipUtils.decompress(data);

StringoutputStr=newString(output);

System.err.println("解压缩后:\t"+outputStr);

System.err.println("长度:\t"+output.length);

assertEquals(inputStr,outputStr);

}

@Test

publicfinalvoidtestFileCompress()throwsException{

FileOutputStreamfos=newFileOutputStream("d:/f.txt");

fos.write(inputStr.getBytes());

fos.flush();

fos.close();

GZipUtils.compress("d:/f.txt",false);

GZipUtils.decompress("d:/f.txt.gz",false);

Filefile=newFile("d:/f.txt");

FileInputStreamfis=newFileInputStream(file);

DataInputStreamdis=newDataInputStream(fis);

byte[]data=newbyte[(int)file.length()];

dis.readFully(data);

fis.close();

StringoutputStr=newString(data);

assertEquals(inputStr,outputStr);

}

}

结果如何?

先看testDataCompress()方法控制台输出结果。

控制台输出如下:

引用

原文: zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org

长度: 52

压缩后:

长度: 45

解压缩后: zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org

长度: 52

这里使用英文字符做测试,当输入字符串的字节数大于50左右时,压缩效果明显;如果这里使用中文压缩,可能当压缩上千字节时方能体现出压缩效果!

对于文件操作,朋友们可以自行实验,我代码里的实现是按照gzip命令来的!

举例来说:

压缩时,将文件a.txt压缩为a.txt.gz,同时删除文件a.txt。

解压缩时,将文件a.txt.gz解压缩为a.txt,同时删除文件a.txt.gz。

注意执行testFileCompress方法,查看产生的文件!

a6558229767b87df3caca2cbd544f611.gif你大可以放到linux上去做验证!

a6558229767b87df3caca2cbd544f611.gif

commons也提供了GZIP算法的实现,甚至更多种压缩算法(tar、bzip2等)的实现,有机会我将继续整理!

a6558229767b87df3caca2cbd544f611.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值