[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,而是改為根據自己需要對流數據進行處理。

參考文獻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM