作者: 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