作者: zyl910 一、緣由 有些時候需要替換zip內的文件。 網上的辦法大多是——先解壓,然後對解壓目錄替換文件,最後再重新壓縮。該辦法需要比較繁瑣,且需要一個臨時目錄。 於是想找無需解壓的方案。 後來找到利用 ZipInputStream、ZipOutputStream 實現該功能的辦法。 二 ...
作者: 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,而是改為根據自己需要對流數據進行處理。
參考文獻
- Javadoc《Class ZipInputStream》. https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/ZipInputStream.html
- Javadoc《Class ZipOutputStream》. https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/ZipOutputStream.html
- zyl910《[Java] 使用ZipInputStream解析zip類文件(jar、docx)的範例》. https://www.cnblogs.com/zyl910/p/java_zip_zipreadtest.html