zoukankan      html  css  js  c++  java
  • [Java] 遍历zip内的数据,逐项复制流来生成新的zip文件的范例(可用于替换zip内的文件)

    作者: zyl910

    一、缘由

    有些时候需要替换zip内的文件。
    网上的办法大多是——先解压,然后对解压目录替换文件,最后再重新压缩。该办法需要比较繁琐,且需要一个临时目录。
    于是想找无需解压的方案。
    后来找到利用 ZipInputStream、ZipOutputStream 实现该功能的办法。

    二、源码

    import java.io.*;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    
    public class ZipCopyTest {
        public static void main(String[] args) {
            String srcPath = "target/classes/static/test.docx";
            String outPath = "E:\test\export\test_copy.docx";
            try(FileInputStream is = new FileInputStream(srcPath)) {
                try(FileOutputStream os = new FileOutputStream(outPath)) {
                    copyZipStream(os, is);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("ZipCopyTest done.");
        }
    
        private static void copyZipStream(OutputStream os, InputStream is) throws IOException {
            try(ZipInputStream zis = new ZipInputStream(is)) {
                try(ZipOutputStream zos = new ZipOutputStream(os)) {
                    ZipEntry se;
                    while ((se = zis.getNextEntry()) != null) {
                        if (null==se) continue;
                        String line = String.format("ZipEntry(%s, isDirectory=%d, size=%d, compressedSize=%d, time=%d, crc=%d, method=%d, comment=%s)",
                                se.getName(), (se.isDirectory())?1:0, se.getSize(), se.getCompressedSize(), se.getTime(), se.getCrc(), se.getMethod(), se.getComment());
                        System.out.println(line);
                        ZipEntry de = new ZipEntry(se);
                        zos.putNextEntry(de);
                        copyStream(zos, zis);
                        zos.closeEntry();
                    }
                }
            }
        }
    
        private static void copyStream(OutputStream os, InputStream is) throws IOException {
            copyStream(os, is, 0);
        }
    
        private static void copyStream(OutputStream os, InputStream is, int bufsize) throws IOException {
            if (bufsize<=0) bufsize= 4096;
            int len;
            byte[] bytes = new byte[bufsize];
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes, 0, len);
            }
        }
    }
    

    现在已经实现zip内项目的逐项复制了。只要稍微改造一下,便能实现“替换zip内的文件”的功能了。
    具体办法是在循环内根据 ZipEntry.getName() 判断当前是哪一个文件,随后不是简单的调用 copyStream,而是改为根据自己需要对流数据进行处理。

    参考文献

  • 相关阅读:
    .NETCORE微服务架构--网关篇(Ocelot)
    Hangfire实战--添加DashBoard登录权限
    IIS发布-HTTP谓词限制访问
    基于Dapper的泛型Repository
    .Net Framework JWT验证
    .Net Framework swagger 进阶----头部参数
    .Net Framework下安装api swagger
    ErrorSet
    201907总结
    博客美化
  • 原文地址:https://www.cnblogs.com/zyl910/p/java_zip_zipcopytest.html
Copyright © 2011-2022 走看看