我目前正在开发一个程序,它一度必须合并两个.zip文件(originalZip和newZip应该合并到moddedZip,newZip覆盖文件,如果它们已经存在的话)。由于我在之前的任何项目中都没有使用.zip文件,因此我搜索了一段时间,直到找到this。虽然它只是附加单个文件,但我认为我能够使用它来合并文件。
这就是我现在所拥有的:
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的文件(不是目录)后,程序似乎崩溃了。我没有得到任何例外,它似乎没有继续。(忘记打印堆栈跟踪),它停止因为它拒绝覆盖现有文件。
这是syso:
copy:test.txt
putnextEntry完成
复制:__ MACOSX /
putnextEntry完成
复制:__ MACOSX /._ test.txt
putnextEntry完成
java.util.zip.ZipFile$1@1fa83e7e
追加:item /
putnextEntry完成
追加:item / .DS_Store
putnextEntry完成
追加:__ MDOSX /
此致 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");
}
}