最近在自學javaWeb,先復習一下java,把還給老師的東西再找回來(知識如果不用很快就會忘記啊)。。
今天看到了zip壓縮,決定要整理一下。
java將有關zip壓縮的內容都封裝在java.util.zip寶中,用java實現zip壓縮,不用考慮壓縮算法,java已經將這些進行了封裝
實際上用java實現zip壓縮涉及的就是一個“輸入輸出流”的概念
用java實現一個文件的zip壓縮,過程可以簡單地表示為:
當然具體實現要比這個復雜一點,比如要先像zip文件中寫入目錄進入點。。如果要壓縮文件夾中的內容要遍歷文件夾中的文件和子文件夾。
先給出源代碼,再解釋:
import java.io.*; import java.util.*; import java.util.zip.*; class ZipCompress { private String zipFileName; // 目的地Zip文件 private String sourceFileName; //源文件(帶壓縮的文件或文件夾) public ZipCompress(String zipFileName,String sourceFileName) { this.zipFileName=zipFileName; this.sourceFileName=sourceFileName; } public void zip() throws Exception { //File zipFile = new File(zipFileName); System.out.println("壓縮中..."); //創建zip輸出流 ZipOutputStream out = new ZipOutputStream( new FileOutputStream(zipFileName)); //創建緩沖輸出流 BufferedOutputStream bos = new BufferedOutputStream(out); File sourceFile = new File(sourceFileName); //調用函數 compress(out,bos,sourceFile,sourceFile.getName()); bos.close(); out.close(); System.out.println("壓縮完成"); } public void compress(ZipOutputStream out,BufferedOutputStream bos,File sourceFile,String base) throws Exception { //如果路徑為目錄(文件夾) if(sourceFile.isDirectory()) { //取出文件夾中的文件(或子文件夾) File[] flist = sourceFile.listFiles(); if(flist.length==0)//如果文件夾為空,則只需在目的地zip文件中寫入一個目錄進入點 { System.out.println(base+"/"); out.putNextEntry( new ZipEntry(base+"/") ); } else//如果文件夾不為空,則遞歸調用compress,文件夾中的每一個文件(或文件夾)進行壓縮 { for(int i=0;i<flist.length;i++) { compress(out,bos,flist[i],base+"/"+flist[i].getName()); } } } else//如果不是目錄(文件夾),即為文件,則先寫入目錄進入點,之后將文件寫入zip文件中 { out.putNextEntry( new ZipEntry(base) ); FileInputStream fos = new FileInputStream(sourceFile); BufferedInputStream bis = new BufferedInputStream(fos); int tag; System.out.println(base); //將源文件寫入到zip文件中 while((tag=bis.read())!=-1) { bos.write(tag); } bis.close(); fos.close(); } } } public class TestZip { public static void main(String[] args) { ZipCompress zipCom = new ZipCompress("D:\\電影.zip","F:\\電影"); try { zipCom.zip(); } catch(Exception e) { e.printStackTrace(); } } }
zip()方法中首先創建了ZipOutputStream(zip輸出流)之后調用compress()方法
在compress()方法中通過遞歸完成將文件夾中的每個文件的壓縮。
具體為:
首先判斷輸入的文件是文件夾還是文件,如果是文件,直接壓縮,如果是文件夾則要遞歸調用compress()遍歷壓縮文件夾中的文件。
如果是文件,首先在zip文件中寫入一個目錄進入點(所謂目錄進入點,個人理解就是源文件在目標zip文件中的路徑)
然后用文件輸入流FileInputStream將源文件讀入內存,在用ZipOutputStream(zip輸出流)將讀入內存的數據寫入到zip文件中,這就完成了壓縮。(實際上就是輸入輸出流)
當文件夾為空的時候,只需寫入一個目錄進入點(要注意最后一定要加一個"\",表示一個目錄)。
運行結果為:
源文件:
其中文件夾1中含有兩個文件,文件夾2 為空。
壓縮后的文件為:
前面提到的空文件夾的目錄進入點一定要加"\",以表示一個文件夾,而不是一個文件,我們可以把程序中的"\"去掉,這時結果為:
可以看到本來是文件夾的文件夾2,編程了文件。所以可以把目錄進入點就理解為,源文件在zip文件中對應的路徑,這個相對路徑應該與源文件夾中的相對路徑一致,當然也可以不一致,比如我們在base前加入一個字符串"我愛",
out.putNextEntry( new ZipEntry("我愛"+base) );
結果為:
可以看到zip中的根目錄變成了“我愛電影”而不是原來的電影
水平有限。。。請多多指教。。。。