使用 java.util.zip 套件實作多檔案壓縮為 ZIP、解壓縮輸出至標準輸出、列出壓縮檔清單。採用 CheckedInputStream/OutputStream 搭配 Adler32 校驗和。
import java.io.*;
import java.util.*;
import java.util.zip.*;
public class ZipDemo {
// 壓縮:參數陣列 args[0] 為輸出 zip 檔名,args[1..] 為欲壓縮檔案
public void zipFiles(String[] args) {
try (FileOutputStream fos = new FileOutputStream(args[0] + ".zip");
CheckedOutputStream cos = new CheckedOutputStream(fos, new Adler32());
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(cos))) {
zos.setComment("Java Zip Test");
for (int i = 1; i < args.length; i++) {
System.out.println("Adding: " + args[i]);
try (BufferedReader br = new BufferedReader(new FileReader(args[i]))) {
zos.putNextEntry(new ZipEntry(args[i]));
int c;
while ((c = br.read()) != -1) zos.write(c);
}
}
System.out.println("Checksum: " + cos.getChecksum().getValue());
} catch (Exception e) { e.printStackTrace(); }
}
// 解壓縮:輸出至 System.out (示範用)
public void unzip(String zipFile) {
try (FileInputStream fis = new FileInputStream(zipFile + ".zip");
CheckedInputStream cis = new CheckedInputStream(fis, new Adler32());
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis))) {
System.out.println("Checksum: " + cis.getChecksum().getValue());
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
System.out.println("Extracting: " + entry.getName());
int b;
while ((b = zis.read()) != -1) System.out.write(b);
}
} catch (Exception e) { e.printStackTrace(); }
}
// 列出壓縮檔內容
public void list(String zipFile) {
try (ZipFile zf = new ZipFile(zipFile + ".zip")) {
Enumeration extends ZipEntry> en = zf.entries();
while (en.hasMoreElements()) System.out.println(en.nextElement());
} catch (Exception e) { e.printStackTrace(); }
}
public static void main(String[] args) {
if (args.length == 0) return;
ZipDemo demo = new ZipDemo();
demo.zipFiles(args);
demo.unzip(args[0]);
demo.list(args[0]);
}
}
改進建議:
Files.copy(zis, targetPath) (Java 8+)。ZipFile 隨機存取而非串流 ZipInputStream。ZipFile(..., StandardCharsets.UTF_8)。