日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

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

發(fā)布時(shí)間:2023/12/3 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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代碼?
  • ?/**?
  • ?*?壓縮包內(nèi)文件名定義?
  • ?*??
  • ?*?<pre>?
  • ?*?如果有多級目錄,那么這里就需要給出包含目錄的文件名?
  • ?*?如果用WinRAR打開壓縮包,中文名將顯示為亂碼?
  • ?*?</pre>?
  • ?*/??
  • 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代碼?
  • /**?
  • ?*?壓縮?
  • ?*??
  • ?*?@param?srcFile?
  • ?*????????????源路徑?
  • ?*?@param?zos?
  • ?*????????????ZipOutputStream?
  • ?*?@param?basePath?
  • ?*????????????壓縮包內(nèi)相對路徑?
  • ?*?@throws?Exception?
  • ?*/??
  • private?static?void?compress(File?srcFile,?ZipOutputStream?zos,??
  • ????????String?basePath)?throws?Exception?{??
  • ????if?(srcFile.isDirectory())?{??
  • ????????compressDir(srcFile,?zos,?basePath);??
  • ????}?else?{??
  • ????????compressFile(srcFile,?zos,?basePath);??
  • ????}??
  • }??
  • ??
  • /**?
  • ?*?壓縮目錄?
  • ?*??
  • ?*?@param?dir?
  • ?*?@param?zos?
  • ?*?@param?basePath?
  • ?*?@throws?Exception?
  • ?*/??
  • private?static?void?compressDir(File?dir,?ZipOutputStream?zos,??
  • ????????String?basePath)?throws?Exception?{??
  • ??
  • ????File[]?files?=?dir.listFiles();??
  • ??
  • ????//?構(gòu)建空目錄??
  • ????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代碼?
  • /**?
  • ?*?2010-4-12?
  • ?*/??
  • 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;??
  • ??
  • /**?
  • ?*?ZIP壓縮工具?
  • ?*??
  • ?*?@author??<a?href="mailto:zlex.dongliang@gmail.com">梁棟</a>????
  • ?*?@since?1.0?
  • ?*/??
  • public?class?ZipUtils?{??
  • ??
  • ????public?static?final?String?EXT?=?".zip";??
  • ????private?static?final?String?BASE_DIR?=?"";??
  • ??
  • ????//?符號"/"用來作為目錄標(biāo)識判斷符??
  • ????private?static?final?String?PATH?=?"/";??
  • ????private?static?final?int?BUFFER?=?1024;??
  • ??
  • ????/**?
  • ?????*?壓縮?
  • ?????*??
  • ?????*?@param?srcFile?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????public?static?void?compress(File?srcFile)?throws?Exception?{??
  • ????????String?name?=?srcFile.getName();??
  • ????????String?basePath?=?srcFile.getParent();??
  • ????????String?destPath?=?basePath?+?name?+?EXT;??
  • ????????compress(srcFile,?destPath);??
  • ????}??
  • ??
  • ????/**?
  • ?????*?壓縮?
  • ?????*??
  • ?????*?@param?srcFile?
  • ?????*????????????源路徑?
  • ?????*?@param?destPath?
  • ?????*????????????目標(biāo)路徑?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????public?static?void?compress(File?srcFile,?File?destFile)?throws?Exception?{??
  • ??
  • ????????//?對輸出文件做CRC32校驗(yàn)??
  • ????????CheckedOutputStream?cos?=?new?CheckedOutputStream(new?FileOutputStream(??
  • ????????????????destFile),?new?CRC32());??
  • ??
  • ????????ZipOutputStream?zos?=?new?ZipOutputStream(cos);??
  • ??
  • ????????compress(srcFile,?zos,?BASE_DIR);??
  • ??
  • ????????zos.flush();??
  • ????????zos.close();??
  • ????}??
  • ??
  • ????/**?
  • ?????*?壓縮文件?
  • ?????*??
  • ?????*?@param?srcFile?
  • ?????*?@param?destPath?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????public?static?void?compress(File?srcFile,?String?destPath)?throws?Exception?{??
  • ????????compress(srcFile,?new?File(destPath));??
  • ????}??
  • ??
  • ????/**?
  • ?????*?壓縮?
  • ?????*??
  • ?????*?@param?srcFile?
  • ?????*????????????源路徑?
  • ?????*?@param?zos?
  • ?????*????????????ZipOutputStream?
  • ?????*?@param?basePath?
  • ?????*????????????壓縮包內(nèi)相對路徑?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????private?static?void?compress(File?srcFile,?ZipOutputStream?zos,??
  • ????????????String?basePath)?throws?Exception?{??
  • ????????if?(srcFile.isDirectory())?{??
  • ????????????compressDir(srcFile,?zos,?basePath);??
  • ????????}?else?{??
  • ????????????compressFile(srcFile,?zos,?basePath);??
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?壓縮?
  • ?????*??
  • ?????*?@param?srcPath?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????public?static?void?compress(String?srcPath)?throws?Exception?{??
  • ????????File?srcFile?=?new?File(srcPath);??
  • ??
  • ????????compress(srcFile);??
  • ????}??
  • ??
  • ????/**?
  • ?????*?文件壓縮?
  • ?????*??
  • ?????*?@param?srcPath?
  • ?????*????????????源文件路徑?
  • ?????*?@param?destPath?
  • ?????*????????????目標(biāo)文件路徑?
  • ?????*??
  • ?????*/??
  • ????public?static?void?compress(String?srcPath,?String?destPath)??
  • ????????????throws?Exception?{??
  • ????????File?srcFile?=?new?File(srcPath);??
  • ??
  • ????????compress(srcFile,?destPath);??
  • ????}??
  • ??
  • ????/**?
  • ?????*?壓縮目錄?
  • ?????*??
  • ?????*?@param?dir?
  • ?????*?@param?zos?
  • ?????*?@param?basePath?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????private?static?void?compressDir(File?dir,?ZipOutputStream?zos,??
  • ????????????String?basePath)?throws?Exception?{??
  • ??
  • ????????File[]?files?=?dir.listFiles();??
  • ??
  • ????????//?構(gòu)建空目錄??
  • ????????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);??
  • ??
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?文件壓縮?
  • ?????*??
  • ?????*?@param?file?
  • ?????*????????????待壓縮文件?
  • ?????*?@param?zos?
  • ?????*????????????ZipOutputStream?
  • ?????*?@param?dir?
  • ?????*????????????壓縮文件中的當(dāng)前路徑?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????private?static?void?compressFile(File?file,?ZipOutputStream?zos,?String?dir)??
  • ????????????throws?Exception?{??
  • ??
  • ????????/**?
  • ?????????*?壓縮包內(nèi)文件名定義?
  • ?????????*??
  • ?????????*?<pre>?
  • ?????????*?如果有多級目錄,那么這里就需要給出包含目錄的文件名?
  • ?????????*?如果用WinRAR打開壓縮包,中文名將顯示為亂碼?
  • ?????????*?</pre>?
  • ?????????*/??
  • ????????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;??
  • ??
  • /**?
  • ?*??
  • ?*?@author?梁棟?
  • ?*?@version?1.0?
  • ?*?@since?1.0?
  • ?*/??
  • 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ò),歡迎將生活随笔推薦給好友。