我正在尝试创建一种方法,只需一步即可将多个zip存档合并到一起。代码看起来非常好,它应该工作。但是当我运行它时,我得到一个非常奇怪的例外:
java.lang.RuntimeException: Unexpected java.util.zip.ZipException ("invalid entry compressed size (expected 1506 but got 1507 bytes)")
(only duplicate entry execptions are expected!)
at io.brainstone.github.installer.FileUtils.makeNewZipFromInputStreamList(FileUtils.java:309)
at io.brainstone.github.installer.Main.startInstalling(Main.java:224)
at io.brainstone.github.installer.Window$3$1.run(Window.java:183)
Caused by: java.util.zip.ZipException: invalid entry compressed size (expected 1506 but got 1507 bytes)
at java.util.zip.ZipOutputStream.closeEntry(Unknown Source)
at java.util.zip.ZipOutputStream.putNextEntry(Unknown Source)
at io.brainstone.github.installer.FileUtils.makeNewZipFromInputStreamList(FileUtils.java:300)
... 2 more
我自己的代码抛出异常。这告诉我发生了意外的异常。预计只会出现duplicate entry
个例外情况。 (这是我用于我的条目覆盖的一个技巧。意味着列表中最后一个的归档具有最高优先级拥有一个文件)
为了清理,这是我的代码:
public static void makeNewZipFromInputStreamList(File outputFile,
ArrayList<InputStream> inputStreamList,
ArrayList<String> includeList, ArrayList<String> excludeList)
throws IOException, IllegalArgumentException {
final int sizeOfLists[] = new int[] { inputStreamList.size(),
includeList.size(), excludeList.size() };
if ((sizeOfLists[0] != sizeOfLists[1])
|| (sizeOfLists[0] != sizeOfLists[2])
|| (sizeOfLists[1] != sizeOfLists[2]))
throw new IllegalArgumentException(
"The ArrayLists do not have the same size ("
+ sizeOfLists[0] + ", " + sizeOfLists[1] + ", "
+ sizeOfLists[2] + ")");
final ZipOutputStream zipOutputFile = new ZipOutputStream(
new FileOutputStream(outputFile));
final int size = sizeOfLists[0];
final InputStream inputStreamTempArray[] = inputStreamList
.toArray(new InputStream[size]);
final String includeArray[] = includeList.toArray(new String[size]);
final String excludeArray[] = excludeList.toArray(new String[size]);
final ZipInputStream inputStreamArray[] = new ZipInputStream[size];
HashMap<String, Object[]> tmp;
int i, j;
String fileName;
ZipEntry entry;
for (i = size - 1; i >= 0; i--) {
inputStreamArray[i] = new ZipInputStream(inputStreamTempArray[i]);
if (includeArray[i] == null) {
includeArray[i] = "";
}
if (excludeArray[i] == null) {
excludeArray[i] = "";
}
while ((entry = inputStreamArray[i].getNextEntry()) != null) {
fileName = entry.getName();
if (fileName.matches(includeArray[i])
|| !fileName.matches(excludeArray[i])) {
try {
zipOutputFile.putNextEntry(entry); // Here is the inital exception thrown!
if (!entry.isDirectory()) {
copyStream(inputStreamArray[i], zipOutputFile,
false, false);
}
} catch (ZipException ex) {
if (!ex.getMessage()
.matches("duplicate entry: .*\\..*")) {
throw new RuntimeException(
"Unexpected "
+ ex.getClass().getName()
+ " (\""
+ ex.getMessage()
+ "\")\n(only duplicate entry execptions are expected!)",
ex);
}
}
}
}
inputStreamArray[i].close();
}
zipOutputFile.close();
}
答案 0 :(得分:1)
如果您使用的是Java SE 7,请考虑使用NIO.2文件API。
请注意,我已经编写了一些实用程序方法,使用NIO.2文件API(该库是开源)将目录复制到Zip文件和从Zip文件复制目录:
的Maven:
<dependency>
<groupId>org.softsmithy.lib</groupId>
<artifactId>softsmithy-lib-core</artifactId>
<version>0.3</version>
</dependency>
教程:
http://softsmithy.sourceforge.net/lib/current/docs/tutorial/nio-file/index.html