我目前正在开发一个程序,该程序在某一时刻必须合并两个 .zip 文件(originalZip 和 newZip 应该合并到 moddedZip,newZip 覆盖文件,如果它们已经存在)。由于我在以前的任何项目中都没有使用 .zip 文件,所以我用谷歌搜索了一段时间,直到找到了这个.zip 文件。虽然它只是附加单个文件,但我认为我可以使用它来合并文件。
这就是我现在所拥有的:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ModZip {
// 4MB buffer
private static final byte[] BUFFER = new byte[4096 * 1024];
// copy input to output stream
public static void copy(InputStream input, OutputStream output) throws IOException {
int bytesRead;
while ((bytesRead = input.read(BUFFER))!= -1) {
output.write(BUFFER, 0, bytesRead);
}
}
public static void patch(String path) throws Exception {
// read the original zip
ZipFile originalZip = new ZipFile(path);
// write the modded zip with new Name
ZipOutputStream moddedZip = new ZipOutputStream(new FileOutputStream(path.substring(0, (path.length()-4))+"-modded.zip"));
// copy contents from original zip to the modded zip
Enumeration<? extends ZipEntry> entries = originalZip.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
System.out.println("copy: " + e.getName());
moddedZip.putNextEntry(e);
System.out.println("putnextEntry done");
if (!e.isDirectory()) {
copy(originalZip.getInputStream(e), moddedZip);
}
moddedZip.closeEntry();
}
// replace the original zip-files with new ones
ZipFile newZip = new ZipFile("/Users/user/Desktop/NEW.zip");
Enumeration<? extends ZipEntry> newentries = newZip.entries();
System.out.println(newentries);
while (newentries.hasMoreElements()) {
ZipEntry e = newentries.nextElement();
System.out.println("append: " + e.getName());
moddedZip.putNextEntry(e);
System.out.println("putnextEntry done");
if (!e.isDirectory()) {
copy(newZip.getInputStream(e), moddedZip);
}
moddedZip.closeEntry();
}
System.out.println("appending done ");
// close
originalZip.close();
newZip.close();
moddedZip.close();
System.out.println("all done");
}
}
将 originalZip 复制到 moddedZip 工作正常,但是在添加第一个条目后,即 newZip 的文件(不是目录)后,程序似乎崩溃了。我没有得到任何例外,它似乎没有继续下去。(忘记打印堆栈跟踪),它停止,因为它拒绝覆盖现有文件。
这是系统:
复制:test.txt
putnext输入完成
复制:__MACOSX/
putnext输入完成
复制:__MACOSX/._test.txt
putnext输入完成
java.util.zip.ZipFile$1@1fa83e7e
附加:项目/
putnext输入完成
附加:item/.DS_Store
putnext输入完成
附加:__MACOSX/
问候 DNSYeti
编辑:感谢 jlordo,我能够自己解决问题,这是新代码:
复制原始 .zip 文件时,它会检查它包含的任何元素是否也在新的 .zip 文件中。如果是,它们将不会被复制到修改后的 .zip 文件中(因此在覆盖它们时我不必再次删除它们)。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ModZip {
// 4MB buffer
private static final byte[] BUFFER = new byte[4096 * 1024];
// copy input to output stream
public static void copy(InputStream input, OutputStream output) throws IOException {
int bytesRead;
while ((bytesRead = input.read(BUFFER))!= -1) {
output.write(BUFFER, 0, bytesRead);
}
}
public static void patch(String path) throws Exception {
// read the zips
ZipFile originalZip = new ZipFile(path);
ZipFile newZip = new ZipFile("/Users/user/Desktop/NEW.zip");
// write the modded zip with new Name
ZipOutputStream moddedZip = new ZipOutputStream(new FileOutputStream(path.substring(0, (path.length()-4))+"-modded.zip"));
// copy contents from original zip to the modded zip
Enumeration<? extends ZipEntry> entries = originalZip.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
String name = e.getName();
if(newZip.getEntry(name) == null) {
System.out.println("copy: " + e.getName());
moddedZip.putNextEntry(e);
System.out.println("putnextEntry done");
if (!e.isDirectory()) {
copy(originalZip.getInputStream(e), moddedZip);
}
moddedZip.closeEntry();
}
}
// replace the original zip-files with new ones
Enumeration<? extends ZipEntry> newentries = newZip.entries();
System.out.println(newentries);
while (newentries.hasMoreElements()) {
ZipEntry e = newentries.nextElement();
System.out.println("append: " + e.getName());
moddedZip.putNextEntry(e);
System.out.println("putnextEntry done");
if (!e.isDirectory()) {
copy(newZip.getInputStream(e), moddedZip);
}
moddedZip.closeEntry();
}
System.out.println("appending done ");
// close
originalZip.close();
newZip.close();
moddedZip.close();
System.out.println("all done");
}
}