java zip打包工具类和使用

经常用到的生成可下载的zip压缩包的工具类和调用示例

import com.xdja.pki.core.exception.ServiceException;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.poi.util.IOUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * zip包打包工具类
 *
 */
public class ZipUtils {

    /**
     * 创建zip包
     * @param srcSource
     * @param fileName  如果是单独一个文件 该变量为文件名
     * @return
     * @throws Exception
     */
    public static byte[] createZipByFile(String srcSource, String fileName) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        //将目标文件打包成zip导出
        File file = new File(srcSource);
        make(zip,file,fileName);
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }

    public static void make(ZipOutputStream zip, File file, String dir) throws Exception {
        //如果当前的是文件夹,则进行进一步处理
        if (file.isDirectory()) {
            //得到文件列表信息
            File[] files = file.listFiles();
            //将文件夹添加到下一级打包目录
            /*
            do 0320 bug 77632 去掉多层文件夹
            zip.putNextEntry(new ZipEntry( dir + "/"));
            dir = dir.length() == 0 ? "" :  dir + "/";
            */
            //循环将文件夹中的文件打包
            for (int i = 0; i < files.length; i++) {
                make(zip, files[i], files[i].getName());         //递归处理
            }
        } else {   //当前的是文件,打包处理
            //文件输入流
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(dir);
            zip.putNextEntry(entry);
            zip.write(FileUtils.readByBinary(file.getPath()));
            IOUtils.closeQuietly(bis);
            zip.flush();
            zip.closeEntry();
        }
    }

    /**
     * 生成zip压缩包保存
     * @param bytes
     * @param strZipName
     * @throws Exception
     */
    public static void generateZipFile(List<Map<String,Object>> bytes,String strZipName) throws Exception {
        ZipOutputStream out = null;
        //压缩文件路径
        File desFile = new File(strZipName);
        if(!desFile.exists()) {
            desFile.getParentFile().mkdirs();
            desFile.createNewFile();
        }
        ZipArchiveOutputStream zous = new ZipArchiveOutputStream(desFile);
        //防止中文乱码
        if(zous instanceof ZipArchiveOutputStream) {
            zous.setEncoding("GBK");
        }
        try {
            zous.setUseZip64(Zip64Mode.AsNeeded);
            for (int i=0;i<bytes.size();i++) {
                String name = (String) bytes.get(i).get("name");
                String suffix = (String) bytes.get(i).get("suffix");

                // 前面几个参数只是为了命名文件,这个by才是二进制文件,是byte[]的形式
                byte[] by = (byte[]) bytes.get(i).get("buffer");
                String filename = name+"."+suffix;
                ArchiveEntry entry = new ZipArchiveEntry(filename);
                zous.putArchiveEntry(entry);
                zous.write(by);
                zous.closeArchiveEntry();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            zous.close();
        }
    }

    /**
     * 生成zip文件的的字节流形式
     * @param bytes
     * @return
     * @throws Exception
     */
    public static byte[] generateZipByte(List<Map<String,Object>> bytes) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(outputStream);
            for (int i=0;i<bytes.size();i++) {
                String name = (String) bytes.get(i).get("name");
                String suffix = (String) bytes.get(i).get("suffix");

                // 前面几个参数只是为了命名文件,这个by才是二进制文件,是byte[]的形式
                byte[] by = (byte[]) bytes.get(i).get("buffer");
                String filename = name+"."+suffix;
                ArchiveEntry entry = new ZipArchiveEntry(filename);
                out.putNextEntry(new ZipEntry(name+"."+suffix));
                out.write(by);
                out.closeEntry();
                out.flush();
            }
        } catch (Exception e) {
            throw new ServiceException(e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
        return outputStream.toByteArray();
    }

    /**
     * 读取文件二进制内容
     *
     * @param path
     * @return
     * @throws IOException
     */
    public static byte[] readByBinary(String path) {
        InputStream inputStream = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            inputStream = new FileInputStream(path);
            int c = 0;
            byte[] bytes = new byte[1024];
            while ((c = inputStream.read(bytes)) != -1) {
                baos.write(bytes, 0, c);
            }
            inputStream.close();
        } catch (Exception e) {
            throw new RuntimeException("读取文件二进制内容异常" + e.getMessage(), e);
        }
        return baos.toByteArray();
    }

    public static void main(String[] args) {

        List<Map<String,Object>> list = new ArrayList<>();

        Map<String,Object> signMap = new HashMap<>();
        signMap.put("name","signCert");
        signMap.put("suffix","cer");
        byte[] signByte = readByBinary("E:\\home\\sign.cer");
        signMap.put("buffer",signByte);
        list.add(signMap);

        Map<String,Object> encMap = new HashMap<>();
        encMap.put("name","encCert");
        encMap.put("suffix","cer");
        byte[] encByte = readByBinary("E:\\home\\enc.cer");
        encMap.put("buffer",encByte);
        list.add(encMap);

        try {
            byte[] bytes = ZipUtils.generateZipByte(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
    @RequestMapping(value = "/v1/download/{applyNo}", method = RequestMethod.GET)
    public Object downloadUserCert(@PathVariable String applyNo, HttpServletResponse resp){
        try {
            String zipPath = "/home/file"+ applyNo;
            String fileName = applyNo +".zip";
            byte[] data = ZipUtils.createZipByFile(zipPath, fileName);
            resp.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            resp.setCharacterEncoding("UTF-8");
            resp.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            OutputStream out = resp.getOutputStream();
            IOUtils.write(data, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error("导出zip压缩包失败,原因:{}", e.getMessage());
            return ErrorEnum.MAKE_ZIP_FILE_EXCEPTION.resp(resp);
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值