相關鏈接:?
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方法。簡單調用如下文所示:?
- /** ?
- ?*?數據壓縮 ?
- ?*? ?
- ?*?@param?is ?
- ?*?@param?os ?
- ?*?@throws?Exception ?
- ?*/ ??
- public ? static ? void ?compress(InputStream?is,?OutputStream?os)??
- ???????? throws ?Exception?{??
- ??
- ????GZIPOutputStream?gos?=? new ?GZIPOutputStream(os);??
- ??
- ???? int ?count;??
- ???? byte ?data[]?=? new ? byte [BUFFER];??
- ???? while ?((count?=?is.read(data,? 0 ,?BUFFER))?!=?- 1 )?{??
- ????????gos.write(data,? 0 ,?count);??
- ????}??
- ??
- ????gos.finish();??
- ??
- ????gos.flush();??
- ????gos.close();??
- }??
記得完成操作后,調用finish方法和flush方法!
?
核心的壓縮實現就這么多!
?
對于解壓縮,GZIPInputStream也對應GZIPOutputStream提供了一個帶定長的read方法。簡單調用如下文所示:?
- /** ?
- ?*?數據解壓縮 ?
- ?*? ?
- ?*?@param?is ?
- ?*?@param?os ?
- ?*?@throws?Exception ?
- ?*/ ??
- public ? static ? void ?decompress(InputStream?is,?OutputStream?os)??
- ???????? throws ?Exception?{??
- ??
- ????GZIPInputStream?gis?=? new ?GZIPInputStream(is);??
- ??
- ???? int ?count;??
- ???? byte ?data[]?=? new ? byte [BUFFER];??
- ???? while ?((count?=?gis.read(data,? 0 ,?BUFFER))?!=?- 1 )?{??
- ????????os.write(data,? 0 ,?count);??
- ????}??
- ??
- ????gis.close();??
- }??
就這么簡單!
?核心內容完畢!?
順便補充一下,在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!
。
?
根據這些特性,我補充了相應的文件操作實現,詳見下文!
?
完整實現:?
- /** ?
- ?*?2010-4-13 ?
- ?*/ ??
- package ?org.zlex.commons.io;??
- ??
- import ?java.io.ByteArrayInputStream;??
- import ?java.io.ByteArrayOutputStream;??
- import ?java.io.File;??
- import ?java.io.FileInputStream;??
- import ?java.io.FileOutputStream;??
- import ?java.io.InputStream;??
- import ?java.io.OutputStream;??
- import ?java.util.zip.GZIPInputStream;??
- import ?java.util.zip.GZIPOutputStream;??
- ??
- /** ?
- ?*?GZIP工具 ?
- ?*? ?
- ?*?@author?<a?href="mailto:zlex.dongliang@gmail.com">梁棟</a> ?
- ?*?@since?1.0 ?
- ?*/ ??
- public ? abstract ? class ?GZipUtils?{??
- ??
- ???? public ? static ? final ? int ?BUFFER?=? 1024 ;??
- ???? public ? static ? final ?String?EXT?=? ".gz" ;??
- ??
- ???? /** ?
- ?????*?數據壓縮 ?
- ?????*? ?
- ?????*?@param?data ?
- ?????*?@return ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? byte []?compress( byte []?data)? throws ?Exception?{??
- ????????ByteArrayInputStream?bais?=? new ?ByteArrayInputStream(data);??
- ????????ByteArrayOutputStream?baos?=? new ?ByteArrayOutputStream();??
- ??
- ???????? //?壓縮 ??
- ????????compress(bais,?baos);??
- ??
- ???????? byte []?output?=?baos.toByteArray();??
- ??
- ????????baos.flush();??
- ????????baos.close();??
- ??
- ????????bais.close();??
- ??
- ???????? return ?output;??
- ????}??
- ??
- ???? /** ?
- ?????*?文件壓縮 ?
- ?????*? ?
- ?????*?@param?file ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?compress(File?file)? throws ?Exception?{??
- ????????compress(file,? true );??
- ????}??
- ??
- ???? /** ?
- ?????*?文件壓縮 ?
- ?????*? ?
- ?????*?@param?file ?
- ?????*?@param?delete ?
- ?????*????????????是否刪除原始文件 ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?compress(File?file,? boolean ?delete)? throws ?Exception?{??
- ????????FileInputStream?fis?=? new ?FileInputStream(file);??
- ????????FileOutputStream?fos?=? new ?FileOutputStream(file.getPath()?+?EXT);??
- ??
- ????????compress(fis,?fos);??
- ??
- ????????fis.close();??
- ????????fos.flush();??
- ????????fos.close();??
- ??
- ???????? if ?(delete)?{??
- ????????????file.delete();??
- ????????}??
- ????}??
- ??
- ???? /** ?
- ?????*?數據壓縮 ?
- ?????*? ?
- ?????*?@param?is ?
- ?????*?@param?os ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?compress(InputStream?is,?OutputStream?os)??
- ???????????? throws ?Exception?{??
- ??
- ????????GZIPOutputStream?gos?=? new ?GZIPOutputStream(os);??
- ??
- ???????? int ?count;??
- ???????? byte ?data[]?=? new ? byte [BUFFER];??
- ???????? while ?((count?=?is.read(data,? 0 ,?BUFFER))?!=?- 1 )?{??
- ????????????gos.write(data,? 0 ,?count);??
- ????????}??
- ??
- ????????gos.finish();??
- ??
- ????????gos.flush();??
- ????????gos.close();??
- ????}??
- ??
- ???? /** ?
- ?????*?文件壓縮 ?
- ?????*? ?
- ?????*?@param?path ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?compress(String?path)? throws ?Exception?{??
- ????????compress(path,? true );??
- ????}??
- ??
- ???? /** ?
- ?????*?文件壓縮 ?
- ?????*? ?
- ?????*?@param?path ?
- ?????*?@param?delete ?
- ?????*????????????是否刪除原始文件 ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?compress(String?path,? boolean ?delete)? throws ?Exception?{??
- ????????File?file?=? new ?File(path);??
- ????????compress(file,?delete);??
- ????}??
- ??
- ???? /** ?
- ?????*?數據解壓縮 ?
- ?????*? ?
- ?????*?@param?data ?
- ?????*?@return ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? byte []?decompress( byte []?data)? throws ?Exception?{??
- ????????ByteArrayInputStream?bais?=? new ?ByteArrayInputStream(data);??
- ????????ByteArrayOutputStream?baos?=? new ?ByteArrayOutputStream();??
- ??
- ???????? //?解壓縮 ??
- ??
- ????????decompress(bais,?baos);??
- ??
- ????????data?=?baos.toByteArray();??
- ??
- ????????baos.flush();??
- ????????baos.close();??
- ??
- ????????bais.close();??
- ??
- ???????? return ?data;??
- ????}??
- ??
- ???? /** ?
- ?????*?文件解壓縮 ?
- ?????*? ?
- ?????*?@param?file ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?decompress(File?file)? throws ?Exception?{??
- ????????decompress(file,? true );??
- ????}??
- ??
- ???? /** ?
- ?????*?文件解壓縮 ?
- ?????*? ?
- ?????*?@param?file ?
- ?????*?@param?delete ?
- ?????*????????????是否刪除原始文件 ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?decompress(File?file,? boolean ?delete)? throws ?Exception?{??
- ????????FileInputStream?fis?=? new ?FileInputStream(file);??
- ????????FileOutputStream?fos?=? new ?FileOutputStream(file.getPath().replace(EXT,??
- ???????????????? "" ));??
- ????????decompress(fis,?fos);??
- ????????fis.close();??
- ????????fos.flush();??
- ????????fos.close();??
- ??
- ???????? if ?(delete)?{??
- ????????????file.delete();??
- ????????}??
- ????}??
- ??
- ???? /** ?
- ?????*?數據解壓縮 ?
- ?????*? ?
- ?????*?@param?is ?
- ?????*?@param?os ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?decompress(InputStream?is,?OutputStream?os)??
- ???????????? throws ?Exception?{??
- ??
- ????????GZIPInputStream?gis?=? new ?GZIPInputStream(is);??
- ??
- ???????? int ?count;??
- ???????? byte ?data[]?=? new ? byte [BUFFER];??
- ???????? while ?((count?=?gis.read(data,? 0 ,?BUFFER))?!=?- 1 )?{??
- ????????????os.write(data,? 0 ,?count);??
- ????????}??
- ??
- ????????gis.close();??
- ????}??
- ??
- ???? /** ?
- ?????*?文件解壓縮 ?
- ?????*? ?
- ?????*?@param?path ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?decompress(String?path)? throws ?Exception?{??
- ????????decompress(path,? true );??
- ????}??
- ??
- ???? /** ?
- ?????*?文件解壓縮 ?
- ?????*? ?
- ?????*?@param?path ?
- ?????*?@param?delete ?
- ?????*????????????是否刪除原始文件 ?
- ?????*?@throws?Exception ?
- ?????*/ ??
- ???? public ? static ? void ?decompress(String?path,? boolean ?delete)? throws ?Exception?{??
- ????????File?file?=? new ?File(path);??
- ????????decompress(file,?delete);??
- ????}??
- ??
- }??
羅嗦了半天,到底行不行??
來個測試用例,測試用例如下所示:?
- /** ?
- ?*?2010-4-13 ?
- ?*/ ??
- package ?org.zlex.commons.compress.compress;??
- ??
- import ? static ?org.junit.Assert.assertEquals;??
- ??
- import ?java.io.DataInputStream;??
- import ?java.io.File;??
- import ?java.io.FileInputStream;??
- import ?java.io.FileOutputStream;??
- ??
- import ?org.junit.Test;??
- ??
- /** ?
- ?*?@author?<a?href="mailto:zlex.dongliang@gmail.com">梁棟</a> ?
- ?*?@since?1.0 ?
- ?*/ ??
- public ? class ?GZipUtilsTest?{??
- ??
- ???? private ?String?inputStr?=? "zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org" ;??
- ??
- ???? @Test ??
- ???? public ? final ? void ?testDataCompress()? throws ?Exception?{??
- ??
- ????????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);??
- ????????String?outputStr?=? new ?String(output);??
- ????????System.err.println( "解壓縮后:\t" ?+?outputStr);??
- ????????System.err.println( "長度:\t" ?+?output.length);??
- ??
- ????????assertEquals(inputStr,?outputStr);??
- ??
- ????}??
- ??
- ???? @Test ??
- ???? public ? final ? void ?testFileCompress()? throws ?Exception?{??
- ??
- ????????FileOutputStream?fos?=? new ?FileOutputStream( "d:/f.txt" );??
- ??
- ????????fos.write(inputStr.getBytes());??
- ????????fos.flush();??
- ????????fos.close();??
- ??
- ????????GZipUtils.compress( "d:/f.txt" ,? false );??
- ??
- ????????GZipUtils.decompress( "d:/f.txt.gz" ,? false );??
- ??
- ????????File?file?=? new ?File( "d:/f.txt" );??
- ??
- ????????FileInputStream?fis?=? new ?FileInputStream(file);??
- ??
- ????????DataInputStream?dis?=? new ?DataInputStream(fis);??
- ??
- ???????? byte []?data?=? new ? byte [( int )?file.length()];??
- ????????dis.readFully(data);??
- ??
- ????????fis.close();??
- ??
- ????????String?outputStr?=? new ?String(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方法,查看產生的文件!
?你大可以放到linux上去做驗證!
?
commons也提供了GZIP算法的實現,甚至更多種壓縮算法(tar、bzip2等)的實現,有機會我將繼續整理!
?
相關鏈接:?
Java壓縮技術(一) ZLib
?
Java壓縮技術(二) ZIP壓縮——Java原生實現
?
Java壓縮技術(三) ZIP解壓縮——Java原生實現
?
Java壓縮技術(四) GZIP——Java原生實現
?
Java壓縮技術(五) GZIP相關——瀏覽器解析
?
Java壓縮技術(六) BZIP2——Commons實現
?
Java壓縮技術(七) TAR——Commons實現
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
