生活随笔
收集整理的這篇文章主要介紹了
Java压缩技术(四) GZIP——Java原生实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自??Java壓縮技術(四) GZIP——Java原生實現
GZIP常常用在linxu環境下,是一種非常簡單的壓縮算法。在Java實現API中,它僅僅包含兩個實現類:GZIPInputStream和GZIPOutputStream。?
GZIPOutputStream類用于壓縮?
GZIPInputStream類用于解壓縮?
先說壓縮實現,GZIPOutputStream只有一個方法用于壓縮,就是帶定長的write方法。簡單調用如下文所示:?
Java代碼?
????????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方法。簡單調用如下文所示:?
Java代碼??
????????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!。
?
根據這些特性,我補充了相應的文件操作實現,詳見下文!
完整實現:?
Java代碼??
????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;???????????public?abstract?class?GZipUtils?{????????public?static?final?int?BUFFER?=?1024;??????public?static?final?String?EXT?=?".gz";????????????????????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;??????}???????????????????public?static?void?compress(File?file)?throws?Exception?{??????????compress(file,?true);??????}?????????????????????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();??????????}??????}????????????????????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();??????}???????????????????public?static?void?compress(String?path)?throws?Exception?{??????????compress(path,?true);??????}?????????????????????public?static?void?compress(String?path,?boolean?delete)?throws?Exception?{??????????File?file?=?new?File(path);??????????compress(file,?delete);??????}????????????????????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;??????}???????????????????public?static?void?decompress(File?file)?throws?Exception?{??????????decompress(file,?true);??????}?????????????????????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();??????????}??????}????????????????????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();??????}???????????????????public?static?void?decompress(String?path)?throws?Exception?{??????????decompress(path,?true);??????}?????????????????????public?static?void?decompress(String?path,?boolean?delete)?throws?Exception?{??????????File?file?=?new?File(path);??????????decompress(file,?delete);??????}????}??
羅嗦了半天,到底行不行??
來個測試用例,測試用例如下所示:?
Java代碼?
????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;?????????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等)的實現,有機會我將繼續整理!
- gzip.rar?(1.5 KB)
- 下載次數: 516
總結
以上是生活随笔為你收集整理的Java压缩技术(四) GZIP——Java原生实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。