Zip条目

原文地址

 

 

zip文件结构

     Zip条目_第1张图片

     上面中的每一行都是一个条目,zip文件就是由一个或者多个条目组成。

     条目在Java中对应ZipEntry类

     

 

创建zip压缩文件

     知道了zip文件结构之后,大概就知道怎么去创建一个zip压缩文件了。

     之前,先了解下创建普通的文件都是经过以下几个步骤:

     1、创建文件输出流FileOutputStream fout = new FileOutputStream(new File("XXX"));

     2、往文件输出流中写入文件内容,fout.write(XXX);

     3、关闭输出流fout.close();

     这样,一个普通的创建就是生成了

 

     既然zip压缩文件也是文件,那么它的创建也基本都差不多,只是,zip文件结构跟普通文件有点差别,因为它里面是由条目(ZipEntry)组成的。

     所以创建zip压缩文件的步骤如下:

     1、创建zip压缩文件输出流

           ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File("XXX")));

 

     2、创建zip文件条目

           ZipEntry entry = new ZipEntry(name)

           备注:name指定条目的名称,例如上图显示的client.cer,这里name可以带路径,例如:a/b/c/test.txt,这样就是创建a/b/c这个目录。

 

     3、将条目添加到zip文件输出流

          zos.putNextEntry(entry);

     

     4、创建被文件的输入流,读取文件内容,并写入到zip压缩文件输出流。这个时候,写入的内容都属于当前这个条目的。

         FileInputStream in = new FileInputStream(new File("XXX"));

     byte[]buffer = new byte[1024];

     int len = 0;

     while((len = in.read(buffer))!=-1){

          zos.write(buffer ,0 ,len);

     }

     in.close();

 

     

     5、关闭zip文件输出流

         zos.close()

 

 

zip乱码问题解决

       使用Apache中的org.apache.tools.zip.ZipOutputStream类来替换Java自带的ZipOutputStream类

       FileOutputStream fout = new FileOutputStream("f:\\abc.zip");

    ZipOutputStream out = new ZipOutputStream(fout);

    out.setEncoding("utf-8"); //这条语句时必须的,否则,生成中文条目时,无法打开zip文件或者出现乱码

    ZipEntry entry = new ZipEntry("测试文件.txt");

    out.putNextEntry(entry);

 

误解区:

    以前都是以为一个文件或者目录就对应zip文件中的一个条目,其实并非一定是这样的。解析如下:

    zip文件是以条目来组织,操作zip文件都是基于条目来进行的,因此,每次往条目新增内容时,

    得首先创建zip文件条目,并将添加到zip文件输出,之后,zip输出流,才认为之后写入到输出流中的

    内容都是属于这个条目,直到zip输出流中新增新的条目。不过一般来正常来说,都是一个文件或者目录就对应zip文件中的一个条目。

    

    正常情况下,一个文件或者目录对应一个条目,如下图:

    Zip条目_第2张图片

       

       但是也可以将a.txt、b.txt的内容都只写入的一个条目c.txt

       Zip条目_第3张图片

 

       生成的zip文件结果图:

       Zip条目_第4张图片

       这里可以发现,只要没有重新往zip文件输出流中添加新的条目,那么,所有的内容都是写入当前条目中。

 

 

自己封装的一个zip压缩工具类

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.util.ArrayList;

import java.util.zip.ZipEntry;

import java.util.zip.ZipOutputStream;

public class FilleUtils {

    

    

    /**

     * zip压缩文件,默认生成的压缩文件目录与当前需要压缩的文件或者目录同级

     * @param filePath  需要压缩的文件或者目录

     * @return 返回zip压缩文件路径

     */

    public static String zip(String filePath) throws Exception{

         System.out.println("压缩中..."); 

         String zipFilePath = null;

         File srcFile = new File(filePath);

         

         //获得zip文件路径

         if(srcFile.isDirectory()){

             zipFilePath = srcFile.getParent() + srcFile.getName() + ".zip";

         }

         else{

             String zipFileName = "";

             if(srcFile.getName().indexOf(".")>-1)

                 zipFileName = srcFile.getName().substring(0 ,srcFile.getName().lastIndexOf(".")) + ".zip";

             else

                 zipFileName = srcFile.getName() + ".zip";

             zipFilePath = srcFile.getParent() + zipFileName;

         }

         

         //开始进行压缩

         ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));   

         BufferedOutputStream bo = new BufferedOutputStream(out);  

         zip(out, srcFile, srcFile.getName(), bo);  

         bo.close();  

         out.close(); 

         System.out.println("压缩完成");  

         

         return zipFilePath;

    }

    

    

    /**

     * zip压缩文件

     * @param filePath

     * @param zipFilePath

     */

    public static void zip(String filePath ,String zipFilePath) throws Exception{

         System.out.println("压缩中..."); 

         File srcFile = new File(filePath);

         

         //检查压缩文件路径是否存在,不存在则创建

         File zipFile = new File(zipFilePath);

         if(!zipFile.exists()){

             zipFile.getParentFile().mkdirs();

         }

         

         //开始压缩

         ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));   

         BufferedOutputStream bo = new BufferedOutputStream(out);  

         zip(out, srcFile, srcFile.getName(), bo);  

         bo.close();  

         out.close();  

         System.out.println("压缩完成");  

    }

    

    

    

    /**

     * 压缩指定的多个文件或者目录

     * @param filePathList

     * @param zipFilePath

     * @throws Exception

     */

    public static void zip(ArrayList filePathList , String zipFilePath) throws Exception{

         System.out.println("压缩中...");

         //检查压缩文件路径是否存在,不存在则创建

         File zipFile = new File(zipFilePath);

         if(!zipFile.exists()){

             zipFile.getParentFile().mkdirs();

         }

        

         //开始压缩

         ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));  

         BufferedOutputStream bo = new BufferedOutputStream(out); 

         if(filePathList==null || filePathList.size()==0){

             throw new RuntimeException("没有指定需要压缩的文件");

         }

         for(String filePath :filePathList){

             File srcFile = new File(filePath);

             zip(out, srcFile, srcFile.getName(), bo); 

         }

         bo.close();  

         out.close(); 

         System.out.println("压缩完成"); 

    }

    

    

    

    private static void zip(ZipOutputStream out , File srcFile ,String base ,BufferedOutputStream bo) throws Exception{

        

        //如果需要压缩的文件是目录,则进行递归压缩处理

        if(srcFile.isDirectory()){

            File[] fileList = srcFile.listFiles();  

            

            //如果是空目录,也需要将该目录压缩进去,注意,此时zipentry的name必须以“/"结束

            if (fileList.length == 0) {  

                out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base  

                out.closeEntry();

            }  

            for (int i = 0; i < fileList.length; i++) {  

                zip(out, fileList[i], base + "/" + fileList[i].getName(), bo); // 递归遍历子文件夹  

            } 

        }

        else{

            out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base  

            FileInputStream in = new FileInputStream(srcFile);  

            byte[]buffer = new byte[1024];

            int len = 0;

            while((len = in.read(buffer))!=-1){

                out.write(buffer ,0 ,len);

            }  

            in.close(); // 输入流关闭 

        }

    } 

 

 

 

你可能感兴趣的:(android基础知识)