欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java中往zip压缩包追加文件

程序员文章站 2022-04-15 15:13:56
有个需求,从某个接口下载的一个zip压缩包,往里面添加一个说明文件。搜索了一下,没有找到往zip直接添加文件的方法,最终解决方法是先解压、再压缩。具体过程如下: ......

有个需求,从某个接口下载的一个zip压缩包,往里面添加一个说明文件。搜索了一下,没有找到往zip直接添加文件的方法,最终解决方法是先解压、再压缩。

具体过程如下:

1、一个zip文件的压缩和解压工具类

压缩和解压工具类来自https://www.iteye.com/blog/songfeng-123-2243016,但是原文代码因为用的是java自带的java.util.zip,有中文乱码的bug,所以需要修改部分代码,并且修改为引用org.apache.tools.zip.*,pom.xml加入依赖包,如下:

        <dependency>
            <groupid>org.apache.ant</groupid>
            <artifactid>ant</artifactid>
            <version>1.10.7</version>
        </dependency>

工具类代码:

package com.example.demo;

import java.io.*;
import java.util.arraylist;
import java.util.enumeration;
import java.util.list;
import java.util.zip.zipexception;

import org.apache.tools.zip.*;

public class ziputil {

    private static int buffersize = 1024;

    /**
     * 压缩
     *
     * @param paths
     * @param filename
     */
    public static void zip(list<string> paths, string filename) {
        zipoutputstream zos = null;
        try {
            zos = new zipoutputstream(new fileoutputstream(filename));
            for (string filepath : paths) {
                // 递归压缩文件
                file file = new file(filepath);
                string relativepath = file.getname();
                if (file.isdirectory()) {
                    relativepath += file.separator;
                }
                zipfile(file, relativepath, zos);
            }
        } catch (ioexception e) {
            e.printstacktrace();
        } finally {
            try {
                if (zos != null) {
                    zos.close();
                }
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }
    }

    public static void zipfile(file file, string relativepath, zipoutputstream zos) {
        inputstream is = null;
        try {
            if (!file.isdirectory()) {
                zipentry zp = new zipentry(relativepath);
                zos.putnextentry(zp);
                is = new fileinputstream(file);
                byte[] buffer = new byte[buffersize];
                int length = 0;
                while ((length = is.read(buffer)) >= 0) {
                    zos.write(buffer, 0, length);
                }
                zos.setencoding("gbk");//解决文件名中文乱码
                zos.flush();
                zos.closeentry();
            } else {
                string temppath = null;
                for (file f : file.listfiles()) {
                    temppath = relativepath + f.getname();
                    if (f.isdirectory()) {
                        temppath += file.separator;
                    }
                    zipfile(f, temppath, zos);
                }
            }
        } catch (ioexception e) {
            e.printstacktrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }
    }

    /**
     * 解压缩
     *
     * @param filename
     * @param path
     */
    public static list<string> unzip(string filename, string path) {
        fileoutputstream fos = null;
        inputstream is = null;
        list<string> filepaths = new arraylist<string>();
        try {
            zipfile zf = new zipfile(new file(filename));
            enumeration en = zf.getentries();
            while (en.hasmoreelements()) {
                zipentry zn = (zipentry) en.nextelement();
                if (!zn.isdirectory()) {
                    is = zf.getinputstream(zn);
                    file f = new file(path + zn.getname());
                    file file = f.getparentfile();
                    file.mkdirs();
                    fos = new fileoutputstream(path + zn.getname());
                    int len = 0;
                    byte bufer[] = new byte[buffersize];
                    while (-1 != (len = is.read(bufer))) {
                        fos.write(bufer, 0, len);
                    }
                    fos.close();
                    filepaths.add(path + zn.getname());
                }
            }
        } catch (zipexception e) {
            e.printstacktrace();
        } catch (ioexception e) {
            e.printstacktrace();
        } finally {
            try {
                if (null != is) {
                    is.close();
                }
                if (null != fos) {
                    fos.close();
                }
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }
        return filepaths;
    }
 }

2、测试

有如下目录结构:
d:\测试\文档.zip
d:\测试\说明.pdf
把“说明.pdf”添加到“文档.zip”里面,生成一个新压缩包“文档(新).zip”。

package com.example.demo;

import java.io.file;
import java.util.list;

public class ziputiltest {
    public static void main(string[] args) {
        //解压
        list<string> files = ziputil.unzip("d:/测试/文档.zip", "d:/测试/");
        //集合添加文件
        files.add("d:/测试/说明.pdf");
        //压缩
        ziputil.zip(files,"d:/测试/文档(新).zip");
        //保留说明.pdf
        files.remove(files.size()-1);
        //删除上面解压出来的文件
        for(string f : files){
            file file = new file(f);
            if(file.exists()){
                file.delete();
            }
        }
    }
}