Java檔案壓縮與解壓縮(二)

來源:互聯網
上載者:User
package com.cn;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.Enumeration;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.zip.ZipOutputStream;//錯誤小結://1 關於file.isFile()與file.isDirectory()記憶出了偏差.//  錯誤以為若是Directory一定是file,file不一定是Directory//  更正:file和Directory是兩碼事.只能是file或Directory中其中一個.//  要看的1 傳入一個路徑直接壓縮了.//2 並不是說我們執行一句File f=new File("F:\\x.txt");//  在本地硬碟上就產生了一個x.txt檔案.而應該進行如下的//  操作才可以.//  File f=new File("F:\\x.txt");//  if (!f.exists()) {//   f.createNewFile();//  }// 其中f.createNewFile()表示建立了一個空檔案//// 多數的情況下,我們執行了File f=new File("F:\\x.txt")// 以後再利用輸入資料流,輸出資料流對f進行操作,比如往該x.txt檔案中// 寫入hello world// //3 血的教訓://  zip()方法中沒有關閉流zos.導致壓縮後的檔案解壓時出錯//重要總結://1 關於zip和unzip的核心操作對象是每一個檔案!!!//  比如碰到一個directory,那麼會去遍曆裡面的每一個檔案,挨個對其進行壓縮.//  不要錯誤地理解,若是一個directory,那麼會將其作為一個整體進行壓縮.//2 在JAVA中每一個壓縮檔都用一個ZipEntry表示//  所以在壓縮的過程中要得到每個檔案的完整路徑(從最外層檔案夾至檔案本身)//  用此完整路徑為每個壓縮檔new()一個ZipEntry//3 所以利用zipEntry可記錄原來的目錄層次.解壓後才保持原樣//  也可以看到在解壓時利用entrys.hasMoreElements()來挨個//  解壓每個zipEntry.//  參見解壓中的代碼://  new File(unzipPath+File.separator+entry.getName());public class TestZipAndUnZip {   public static void main(String[] args) throws Exception {   TestZipAndUnZip test=new TestZipAndUnZip();   //將某一個檔案壓縮成zip   test.zip("F:\\", "kk\\cc.txt", "F:\\cc1.zip");   //將某一個zip解壓   test.unZipFile("F:\\cc1.zip", "F:\\zzzz");   }   /** * @param willZipDirPath    被壓縮檔(目錄)所在目錄 * @param willZipFileName   被壓縮檔(目錄)的名稱 * @param toFilePath        壓縮後檔案(目錄)名 */public void zip(String willZipDirPath, String willZipFileName, String zipedFileName) {System.out.println("…………………以下為zip()方法…………………………");if (willZipDirPath == null) {return;}File willZipDir = new File(willZipDirPath);if (!willZipDir.exists() || !willZipDir.isDirectory()) {return;}// 獲得目錄絕對路徑String willZipDirAbsolutePath = willZipDir.getAbsolutePath();System.out.println("willZipDir.getAbsolutePath()="+willZipDirAbsolutePath);//壓縮後的檔案File zipedFile = new File(zipedFileName);try {//從壓縮後的檔案得到壓縮輸出資料流ZipOutputStream//這裡的zos只指向了壓縮後檔案的最外層.那麼它怎麼//維持了原來的目錄結構呢?//就是利用了ZipEntry!!!//在fileToZip()方法中就可以看到ZipEntry的使用!!ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipedFile));if (willZipFileName.equals("*")) {//若傳入的是*表示將此路徑下所有東西都要壓縮//所以調用dirToZip()dirToZip(willZipDirAbsolutePath, willZipDir, zos);} else {//將被壓縮的檔案File willZipFile = new File(willZipDirPath, willZipFileName);if (willZipFile.isFile()) {System.out.println("…………………最外層開始壓縮檔………………………");fileToZip(willZipDirPath, willZipFile, zos);System.out.println("…………………最外層壓縮檔結束………………………");}if (willZipFile.isDirectory()) {System.out.println("…………………最外層開始壓縮目錄………………………");dirToZip(willZipDirPath, willZipFile, zos);System.out.println("…………………最外層壓縮目錄結束………………………");}// 關閉流!!!zos.close();System.out.println("…………………以上為zip()方法…………………………");}} catch (Exception e) {// TODO: handle exception}}   /** * @param dirPath      被壓縮檔所在目錄 * @param willZipFile  被壓縮檔的名稱 * @param zos          輸出資料流 */public void fileToZip(String dirPath, File willZipFile,ZipOutputStream zos){   FileInputStream fis=null;   ZipEntry zipEntry=null;   byte [] buffer=new byte[1024*8];   int len=0;   if (willZipFile.isFile()) {try {fis=new FileInputStream(willZipFile);zipEntry=new ZipEntry(getEntryName(dirPath, willZipFile));zos.putNextEntry(zipEntry);System.out.println("…………………以下為fileToZip()方法…………………………");System.out.println("zipEntry.getName="+zipEntry.getName());System.out.println("zipEntry.isDirectory="+zipEntry.isDirectory());System.out.println("zipEntry.getSize="+zipEntry.getSize());System.out.println("zipEntry.getTime="+zipEntry.getTime());System.out.println("zipEntry.getComment="+zipEntry.getComment());System.out.println("…………………以上為fileToZip()方法…………………………");while((len=fis.read(buffer))!=-1){zos.write(buffer, 0, len);}zos.closeEntry();fis.close();} catch (Exception e) {}}  }/** * @param dirPath     被壓縮目錄所在的上級目錄 * @param willZipDir  被壓縮目錄 * @param zos         輸出資料流 */public void dirToZip(String dirPath, File willZipDir, ZipOutputStream zos) {if (willZipDir.isDirectory()) {File[] files = willZipDir.listFiles();//處理-->該檔案夾下無檔案            if (files.length==0) {ZipEntry zipEntry=new ZipEntry(getEntryName(dirPath, willZipDir));System.out.println("xxxxxxxxxxxxxxxx "+zipEntry.getName());try {zos.putNextEntry(zipEntry);//zos.closeEntry();} catch (Exception e) {e.printStackTrace();}return;}            //處理-->該檔案夾下的所有檔案            for (int i = 0; i < files.length; i++) {File file = files[i];//若是檔案,遞迴調用fileToZip()if (file.isFile()) {System.out.println("xxxxxxxxxx內層開始fileToZip()方法xxxxxxxxxx");fileToZip(dirPath, file, zos);System.out.println("xxxxxxxxxx內層fileToZip()方法結束xxxxxxxxxx");}//若是檔案,遞迴調用dirToZip()if (file.isDirectory()) {System.out.println("xxxxxxxxxx內層開始dirToZip()方法xxxxxxxxxx");dirToZip(dirPath, file, zos);System.out.println("xxxxxxxxxx內層dirToZip()方法結束xxxxxxxxxx");}}}}   /** * @param dirPath      將被壓縮檔所在目錄 * @param willZipFile  將被壓縮的檔案 * @return             *///產生的是每個檔案的完整路徑(從最外層檔案夾至檔案本身)//這樣產生的zipEntry就記錄了原來的目錄層次.解壓後才保持原樣public String getEntryName(String dirPath, File willZipFile) {if (!dirPath.endsWith(File.separator)) {dirPath += File.separator;}String willZipFilePath=willZipFile.getAbsolutePath();if (willZipFile.isDirectory()) {willZipFilePath+="/";}int index=willZipFilePath.indexOf(dirPath);System.out.println("xx返回的 entryName="+ willZipFilePath.substring(index+dirPath.length()));return willZipFilePath.substring(index+dirPath.length());}/** * @param zipedFileName 待解壓zip檔案 * @param unzipDirPath  檔案解壓後的最外層檔案名稱 * @throws IOException  */public void unZipFile(String zipedFileName,String unzipDirPath) throws Exception{if (!unzipDirPath.endsWith(File.separator)) {unzipDirPath+=File.separator;}try {ZipFile zipedFile=new ZipFile(zipedFileName);ZipEntry zipEntry=null;String entryName=null;String unzipedFileName=null;Enumeration entrys=zipedFile.entries();byte [] buffer=new byte[1024*8];int len=0;while (entrys.hasMoreElements()) {zipEntry=(ZipEntry) entrys.nextElement();entryName=zipEntry.getName();unzipedFileName=unzipDirPath+entryName;System.out.println("…………………以下為unZipFile()方法…………………………");System.out.println("zipedFileName="+zipedFileName);System.out.println("unzipDirPath="+unzipDirPath);System.out.println("entryName="+entryName);System.out.println("unzipedFileName="+unzipedFileName);System.out.println("…………………以上為unZipFile()方法…………………………");if (zipEntry.isDirectory()) {//沒有執行此代碼System.out.println("999999999999");new File(unzipedFileName).mkdirs();} else {//總是執行該代碼.因為壓縮的時候是對每個檔案進行壓縮的.                    new File(unzipedFileName).getParentFile().mkdirs();}FileOutputStream fos=null;InputStream is=null;File unzipedFile=new File(unzipedFileName);if (unzipedFile.isDirectory()) {File [] files=unzipedFile.listFiles();for (int i = 0; i < files.length; i++) {File file = files[i]; fos=new FileOutputStream(file); is=zipedFile.getInputStream(zipEntry);while ((len=is.read(buffer))!=-1) {fos.write(buffer, 0, len);}}}else{ fos=new FileOutputStream(unzipedFile); is=zipedFile.getInputStream(zipEntry);   while ((len=is.read(buffer))!=-1) {fos.write(buffer, 0, len);}}//這裡需要修改//fos.close();//is.close();}} catch (Exception e) {e.printStackTrace();}}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.