生活随笔
收集整理的這篇文章主要介紹了
Java压缩技术(二) ZIP压缩——Java原生实现
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
轉(zhuǎn)載自? ?Java壓縮技術(shù)(二) ZIP壓縮——Java原生實(shí)現(xiàn)
查過相關(guān)資料后才知道,ZIP應(yīng)該算作歸檔類的壓縮算法,每一門學(xué)科都可深可淺!?
閑言少敘,先說ZIP壓縮。?
zip壓縮需要通過ZipOutputStream 執(zhí)行write方法將壓縮數(shù)據(jù)寫到指定輸出流中。?
注意,這里應(yīng)先使用CheckedOutputStream 指定文件校驗(yàn)算法。(通常使用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就是壓縮包中的每一個(gè)實(shí)體!?
完成上述準(zhǔn)備后,就可以執(zhí)行壓縮操作了。實(shí)際上,就是執(zhí)行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();??
當(dāng)然,如果待添加的壓縮項(xiàng)是一個(gè)目錄。那么,需要通過遞歸的方式指定最終的壓縮項(xiàng)。?
如果要添加一個(gè)空目錄,注意使用符號"/"(String PATH="/";)作為添加項(xiàng)名字結(jié)尾符!
?
遞歸構(gòu)建目錄壓縮,代碼如下:?
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是一個(gè)空目錄,用WinRAR打開后,可以看到這個(gè)目錄下還有一個(gè)空文件名文件!
?
來個(gè)完整的壓縮實(shí)現(xiàn),代碼如下所示:?
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();??????}????}??
來做個(gè)簡單的測試:?
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");??????}??}??
現(xiàn)在用WinRAR打開看看,是不是效果幾乎一致?
當(dāng)然,上述代碼有所不足之處主要是中文名稱亂碼問題。用java原生ZIP實(shí)現(xiàn)壓縮后得到的壓縮包,與系統(tǒng)的字符集不同,文件/目錄名將出現(xiàn)亂碼。這是所有歸檔壓縮都會遇到的問題。對于這種問題,Commons Copress提供了解決方案!
總結(jié)
以上是生活随笔為你收集整理的Java压缩技术(二) ZIP压缩——Java原生实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。