生活随笔
收集整理的這篇文章主要介紹了
Java压缩技术(二) ZIP压缩——Java原生实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自? ?Java壓縮技術(二) ZIP壓縮——Java原生實現
查過相關資料后才知道,ZIP應該算作歸檔類的壓縮算法,每一門學科都可深可淺!?
閑言少敘,先說ZIP壓縮。?
zip壓縮需要通過ZipOutputStream 執行write方法將壓縮數據寫到指定輸出流中。?
注意,這里應先使用CheckedOutputStream 指定文件校驗算法。(通常使用CRC32算法)。代碼如下所示:?
Java代碼
CheckedOutputStream?cos?=?new?CheckedOutputStream(new?FileOutputStream(destPath),?new?CRC32());??ZipOutputStream?zos?=?new?ZipOutputStream(cos);??
接下來,需要將待壓縮文件以ZipEntry的方式追加到壓縮文件中,如下所示:?
Java代碼?
??????????ZipEntry?entry?=?new?ZipEntry(dir?+?file.getName());????zos.putNextEntry(entry);??
ZipEntry就是壓縮包中的每一個實體!?
完成上述準備后,就可以執行壓縮操作了。實際上,就是執行ZipOutputStream類的write方法,如下所示:?
Java代碼?
BufferedInputStream?bis?=?new?BufferedInputStream(new?FileInputStream(??????????file));????int?count;??byte?data[]?=?new?byte[BUFFER];??while?((count?=?bis.read(data,?0,?BUFFER))?!=?-1)?{??????zos.write(data,?0,?count);??}??bis.close();??
當然,如果待添加的壓縮項是一個目錄。那么,需要通過遞歸的方式指定最終的壓縮項。?
如果要添加一個空目錄,注意使用符號"/"(String PATH="/";)作為添加項名字結尾符!
?
遞歸構建目錄壓縮,代碼如下:?
Java代碼?
????????????private?static?void?compress(File?srcFile,?ZipOutputStream?zos,??????????String?basePath)?throws?Exception?{??????if?(srcFile.isDirectory())?{??????????compressDir(srcFile,?zos,?basePath);??????}?else?{??????????compressFile(srcFile,?zos,?basePath);??????}??}?????????????private?static?void?compressDir(File?dir,?ZipOutputStream?zos,??????????String?basePath)?throws?Exception?{????????File[]?files?=?dir.listFiles();??????????????if?(files.length?<?1)?{??????????ZipEntry?entry?=?new?ZipEntry(basePath?+?dir.getName()?+?PATH);????????????zos.putNextEntry(entry);??????????zos.closeEntry();??????}????????for?(File?file?:?files)?{????????????????????compress(file,?zos,?basePath?+?dir.getName()?+?PATH);??????}??}??
x是一個空目錄,用WinRAR打開后,可以看到這個目錄下還有一個空文件名文件!
?
來個完整的壓縮實現,代碼如下所示:?
Java代碼?
????package?org.zlex.commons.io;????import?java.io.BufferedInputStream;??import?java.io.BufferedOutputStream;??import?java.io.File;??import?java.io.FileInputStream;??import?java.io.FileOutputStream;??import?java.util.zip.CRC32;??import?java.util.zip.CheckedInputStream;??import?java.util.zip.CheckedOutputStream;??import?java.util.zip.ZipEntry;??import?java.util.zip.ZipInputStream;??import?java.util.zip.ZipOutputStream;???????????public?class?ZipUtils?{????????public?static?final?String?EXT?=?".zip";??????private?static?final?String?BASE_DIR?=?"";??????????????private?static?final?String?PATH?=?"/";??????private?static?final?int?BUFFER?=?1024;???????????????????public?static?void?compress(File?srcFile)?throws?Exception?{??????????String?name?=?srcFile.getName();??????????String?basePath?=?srcFile.getParent();??????????String?destPath?=?basePath?+?name?+?EXT;??????????compress(srcFile,?destPath);??????}??????????????????????public?static?void?compress(File?srcFile,?File?destFile)?throws?Exception?{??????????????????????CheckedOutputStream?cos?=?new?CheckedOutputStream(new?FileOutputStream(??????????????????destFile),?new?CRC32());????????????ZipOutputStream?zos?=?new?ZipOutputStream(cos);????????????compress(srcFile,?zos,?BASE_DIR);????????????zos.flush();??????????zos.close();??????}????????????????????public?static?void?compress(File?srcFile,?String?destPath)?throws?Exception?{??????????compress(srcFile,?new?File(destPath));??????}????????????????????????private?static?void?compress(File?srcFile,?ZipOutputStream?zos,??????????????String?basePath)?throws?Exception?{??????????if?(srcFile.isDirectory())?{??????????????compressDir(srcFile,?zos,?basePath);??????????}?else?{??????????????compressFile(srcFile,?zos,?basePath);??????????}??????}???????????????????public?static?void?compress(String?srcPath)?throws?Exception?{??????????File?srcFile?=?new?File(srcPath);????????????compress(srcFile);??????}??????????????????????public?static?void?compress(String?srcPath,?String?destPath)??????????????throws?Exception?{??????????File?srcFile?=?new?File(srcPath);????????????compress(srcFile,?destPath);??????}?????????????????????private?static?void?compressDir(File?dir,?ZipOutputStream?zos,??????????????String?basePath)?throws?Exception?{????????????File[]?files?=?dir.listFiles();??????????????????????if?(files.length?<?1)?{??????????????ZipEntry?entry?=?new?ZipEntry(basePath?+?dir.getName()?+?PATH);????????????????zos.putNextEntry(entry);??????????????zos.closeEntry();??????????}????????????for?(File?file?:?files)?{??????????????????????????????compress(file,?zos,?basePath?+?dir.getName()?+?PATH);????????????}??????}????????????????????????private?static?void?compressFile(File?file,?ZipOutputStream?zos,?String?dir)??????????????throws?Exception?{?????????????????????????????ZipEntry?entry?=?new?ZipEntry(dir?+?file.getName());????????????zos.putNextEntry(entry);????????????BufferedInputStream?bis?=?new?BufferedInputStream(new?FileInputStream(??????????????????file));????????????int?count;??????????byte?data[]?=?new?byte[BUFFER];??????????while?((count?=?bis.read(data,?0,?BUFFER))?!=?-1)?{??????????????zos.write(data,?0,?count);??????????}??????????bis.close();????????????zos.closeEntry();??????}????}??
來做個簡單的測試:?
Java代碼?
import?static?org.junit.Assert.*;????import?org.junit.Test;???????????public?class?ZipUtilsTest?{????????????????@Test??????public?void?test()?throws?Exception?{????????????????????ZipUtils.compress("d:\\f.txt");????????????????????ZipUtils.compress("d:\\fd");??????}??}??
現在用WinRAR打開看看,是不是效果幾乎一致?
當然,上述代碼有所不足之處主要是中文名稱亂碼問題。用java原生ZIP實現壓縮后得到的壓縮包,與系統的字符集不同,文件/目錄名將出現亂碼。這是所有歸檔壓縮都會遇到的問題。對于這種問題,Commons Copress提供了解決方案!
總結
以上是生活随笔為你收集整理的Java压缩技术(二) ZIP压缩——Java原生实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。