Java Zip壓縮實現


最近在自學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中的根目錄變成了“我愛電影”而不是原來的電影

 

 

 水平有限。。。請多多指教。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM