如果有人来到这里试图找到 @HailZeon 代码的 java8 更清洁的重构版本。这里是:
private static final int BUFFER_SIZE = 2048;
public File zip(File source, String zipFileName) throws IOException {
File zipFile = null;
if(source != null) {
File zipFileDestination = new File(getCacheDir(), zipFileName);
if (zipFileDestination.exists()) {
zipFileDestination.delete();
}
zipFile = zip(source, zipFileDestination);
}
return zipFile;
}
public File zip(File source, File zipFile) throws IOException {
int relativeStartingPathIndex = zipFile.getAbsolutePath().lastIndexOf("/") + 1;
if (source != null && zipFile != null) {
try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( new FileOutputStream(zipFile)))) {
if (source.isDirectory()) {
zipSubDir(out, source, relativeStartingPathIndex);
} else {
try (BufferedInputStream origin = new BufferedInputStream(new FileInputStream(source))) {
zipEntryFile(origin, out, source, relativeStartingPathIndex);
}
}
}
}
return zipFile;
}
private void zipSubDir(ZipOutputStream out, File dir, int relativeStartingPathIndex) throws IOException {
File[] files = dir.listFiles();
if (files != null) {
for(File file : files) {
if(file.isDirectory()) {
zipSubDir(out, file, relativeStartingPathIndex);
} else {
try (BufferedInputStream origin = new BufferedInputStream(new FileInputStream(file))) {
zipEntryFile(origin, out, file, relativeStartingPathIndex);
}
}
}
}
}
private void zipEntryFile(BufferedInputStream origin, ZipOutputStream out, File file, int relativeStartingPathIndex) throws IOException {
String relativePath = file.getAbsolutePath().substring(relativeStartingPathIndex);
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(file.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
byte[] data = new byte[BUFFER_SIZE];
int count;
while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) {
out.write(data, 0, count);
}
}