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,而是改为根据自己需要对流数据进行处理。

    参考文献

  • 相关阅读:
    cf B. Sereja and Suffixes
    cf E. Dima and Magic Guitar
    cf D. Dima and Trap Graph
    cf C. Dima and Salad
    最短路径问题(floyd)
    Drainage Ditches(网络流(EK算法))
    图结构练习—BFSDFS—判断可达性(BFS)
    Sorting It All Out(拓扑排序)
    Power Network(最大流(EK算法))
    Labeling Balls(拓扑)
  • 原文地址:https://www.cnblogs.com/zyl910/p/java_zip_zipcopytest.html
Copyright © 2011-2022 走看看