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

    参考文献

  • 相关阅读:
    链表重排 【模板题】
    链表的插入排序
    链表归并排序
    判断链表成环| 删除第K个节点【快慢指针】
    vue骨架屏制作
    前端常用的网站+插件
    点击canvas图片下载图片
    判断dom是否出现在可视区域
    canvas截取图片
    .如果在input上加上@keyup.enter.native,第一次回车时还是会刷新界面,在el-from上加上 @submit.native.prevent
  • 原文地址:https://www.cnblogs.com/zyl910/p/java_zip_zipcopytest.html
Copyright © 2011-2022 走看看