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.ZipInputStream;import java.util.zip.ZipOutputStream;//錯誤小結://1 關於file.isFile()與file.isDirectory()記憶出了偏差.//  錯誤以為若是Directory一定是file,file不一定是Directory//  更正:file和Directory是兩碼事.只能是file或Directory中其中一個.//  要看的1 傳入一個路徑直接壓縮了.//2 血的教訓://  zip()方法中沒有關閉流zos.導致壓縮後的檔案解壓時出錯//重要總結://1 關於zip和unzip的核心操作對象是每一個檔案!!!//  比如碰到一個directory,那麼會去遍曆裡面的每一個檔案,挨個對其進行壓縮.//  不要錯誤地理解,若是一個directory,那麼會將其作為一個整體進行壓縮.//2 在JAVA中每一個壓縮檔都用一個ZipEntry表示//  所以在壓縮的過程中要得到每個檔案的完整路徑(從最外層檔案夾至檔案本身)//  用此完整路徑為每個壓縮檔new()一個ZipEntry//3 所以利用zipEntry可記錄原來的目錄層次.解壓後才保持原樣//  也可以看到在解壓時利用entrys.hasMoreElements()來挨個//  解壓每個zipEntrypublic class TestZipAndUnZip {   public static void main(String[] args) throws Exception {   TestZipAndUnZip test=new TestZipAndUnZip();   //將某一個檔案壓縮成zip//   test.zip("E:\\", "aa\\1.txt", "E:\\cc1.zip");      //將某一個目錄壓縮成zip   //test.zip("E:\\aa", "bb\\", "E:\\zz.zip");//right//    // test.zip("E:\\", "aa", "E:\\zz678910.zip");//right////   //將某一個zip解壓//   test.unZipFile("E:\\zz.zip", "E:\\zzzz");      /////////////////////以下正確///////////////////////////////   //壓縮和解壓單個檔案//   test.zip2("E:\\aa\\1.txt","E:\\aaaaaaa\\aa1234.zip");//   test.unZipFile2("E:\\aaaaaaa\\aa1234.zip", "E:\\aaaaaaa\\aaxixihaha");      //壓縮和解壓一個目錄   test.zip2("D:\\developmentTools","E:\\20.zip");   test.unZipFile2("E:\\20.zip", "E:\\555aaxx99xxx");      /////////////////////以上正確//////////////////////////////   }   /** * @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);System.out.println("ccccccccccc name="+willZipFile.getName());System.out.println("ccccccccccc getAbsolutePath="+willZipFile.getAbsolutePath());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));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()) {//沒有執行此代碼new File(unzipedFileName).mkdirs();} else {//總是執行該代碼.因為壓縮的時候是對每個檔案進行壓縮的.                    new File(unzipedFileName).getParentFile().mkdirs();}File unzipedFile=new File(unzipedFileName);FileOutputStream fos=new FileOutputStream(unzipedFile);InputStream is=zipedFile.getInputStream(zipEntry);while ((len=is.read(buffer))!=-1) {fos.write(buffer, 0, len);}fos.close();is.close();}} catch (Exception e) {e.printStackTrace();}}//////////////////////////////////////////////////////////////////////////////////////** * 該方法將一個給定路徑的檔案壓縮 * @param willZipPath 將要壓縮的檔案的路徑 * @param zipedPath   該檔案壓縮後的路徑 */public void zip2(String willZipPath,String zipedPath){try {File willZipedFile=new File(willZipPath);File zipedFile=new File(zipedPath);ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(zipedFile));if (willZipedFile.isFile()) {fileToZip2(willZipPath,willZipedFile, zos);}if (willZipedFile.isDirectory()) {dirToZip2(willZipPath,willZipedFile, zos);}//方法調用完成後關閉流zos.close();} catch (Exception e) {// TODO: handle exception}}/** * @param rawPath      * @param willZipedFile * @param zos */ //test.zip2("E:\\aa\\1.txt","E:\\aaaaaaa\\aa1234.zip");public void fileToZip2(String rawPath,File willZipedFile,ZipOutputStream zos){try {//執行個體化一個名稱為ab.txt的ZipEntry對象File file=new File(rawPath);ZipEntry entry = new ZipEntry(getEntryName2(rawPath, file));//把產生的ZipEntry對象加入到壓縮檔中//而之後往壓縮檔中寫入的內容都會放在這個ZipEntry對象裡面zos.putNextEntry(entry);InputStream is = new FileInputStream(rawPath);int len = 0;while ((len = is.read()) != -1){zos.write(len);}is.close();//流關閉錯誤了!!//zos.close();} catch (Exception e) {}}/** * @param rawPath     原檔案所在路徑 * @param zipedFile   壓縮後的檔案 * @param zos */public void dirToZip2(String rawPath,File zipedFile, ZipOutputStream zos) {if (zipedFile.isDirectory()) {File[] files = zipedFile.listFiles();//處理-->該檔案夾下無檔案//            if (files.length==0) {////ZipEntry zipEntry=new ZipEntry(getEntryName(dirPath, willZipDir));//ZipEntry zipEntry=new ZipEntry("");//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()) {fileToZip2(file.getAbsolutePath(),file, zos);}//若是檔案,遞迴調用dirToZip()if (file.isDirectory()) {dirToZip2(file.getAbsolutePath(),file, zos);}}}}/** * @param rawPath  需要壓縮的目錄或者檔案的完整路徑 * @param file     需要壓縮的檔案 * @return         entryName */public String getEntryName2(String rawPath,File file){//file是rawPath對應的filetry {String rawDir=rawPath.substring(3);int rawDirIndex=file.getAbsolutePath().indexOf(rawDir);String entryName=file.getAbsolutePath().substring(rawDirIndex);return entryName;} catch (Exception e) {}return null;}/** * @param zipedFilePath  原壓縮檔的路徑 * @param unzipPath      檔案解壓後的路徑 */public void unZipFile2(String zipedFilePath, String unzipPath){try {//解壓後的最外層檔案夾File unzipFile=new File(unzipPath);if (!unzipFile.exists()) {unzipFile.mkdirs();}File zipedFile = new File(zipedFilePath);File perUnzipedFile = null;// 執行個體化ZipFile對象 這個很容易錯!!!!// ZipFile zipFile = new ZipFile(file) ;ZipInputStream zis = new ZipInputStream(new FileInputStream(zipedFile));FileOutputStream fos = null; ZipEntry entry = null; while ((entry = zis.getNextEntry()) != null) { // 得到一個壓縮實體perUnzipedFile = new File(unzipPath+File.separator+entry.getName());if (!perUnzipedFile.getParentFile().exists()) { perUnzipedFile.getParentFile().mkdirs(); // 建立父目錄}if (!perUnzipedFile.exists()) { // 判斷輸出檔案是否存在perUnzipedFile.createNewFile(); // 建立檔案}// 得到每一個實體的輸入資料流fos = new FileOutputStream(perUnzipedFile); int len = 0;while ((len = zis.read()) != -1) {fos.write(len);}}zis.close(); fos.close(); } catch (Exception e) {// TODO: handle exception}}}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.