我一直在调试一些jar-update片段,我遇到了一个zip / unzip组合应该可以反转另一个,但是当我在jar上尝试它时,即使所有文件都存在,它也会失败。任何人都可以找出出错的地方吗?
SSCCE(无需编译):Download here!
package jarsscce;
import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
public class JarSSCCE {
public static void main(String[] args) throws IOException {
File testJar = new File("test.jar");
File testDir = new File("test");
File jarPack = new File("packed_test.jar");
unpack(testJar, testDir);
jar(testDir, jarPack);
}
public static void jar(File directory, File zip) throws IOException {
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(zip))) {
jar(directory, directory, jos);
}
}
private static void jar(File directory, File base, JarOutputStream jos) throws IOException {
File[] files = directory.listFiles();
byte[] buffer = new byte[1 << 12];
if (files.length == 0) {
JarEntry entry = new JarEntry(directory.getPath().substring(base.getPath().length() + 1) + File.separator);
jos.putNextEntry(entry);
} else {
for (int i = 0, n = files.length; i < n; i++) {
if (files[i].isDirectory()) {
jar(files[i], base, jos);
} else {
try (FileInputStream in = new FileInputStream(files[i])) {
JarEntry entry = new JarEntry(files[i].getPath().substring(base.getPath().length() + 1));
jos.putNextEntry(entry);
int read;
while ((read = in.read(buffer, 0, buffer.length)) != -1) {
jos.write(buffer, 0, read);
}
jos.closeEntry();
}
}
}
}
}
public static void unpack(File zip, File extractTo) throws IOException {
try (ZipFile archive = new ZipFile(zip)) {
Enumeration e = archive.entries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
File file = new File(extractTo, entry.getName());
if (entry.isDirectory() && !file.exists()) {
file.mkdirs();
} else {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try (InputStream in = archive.getInputStream(entry)) {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
byte[] buffer = new byte[1 << 13];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
}
}
}
}
}
}
编辑:通过Winrar查看存档信息,我可以看到Netbeans创建的test.jar根本没有压缩,而且程序创建的是。 “主机OS”和“要提取的版本”值也不同。虽然我看不出其中的任何一个会有多重要。
答案 0 :(得分:2)
我想我已经找到了问题,在这个链接上有一个高峰:http://viralpatel.net/blogs/creating-zip-and-jar-files-in-java/。它讨论了使用entry.setMethod(ZipEntry.STORED)
然而我们必须创建自己的校验和等,但它在链接中都有解释。
<强>附录:强>
使用不同的zip()
方法让它工作:
import java.io.*;
import java.net.URI;
import java.util.Deque;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class Main {
public static void main(String[] args) throws IOException {
File testJar = new File("test.jar");
File testDir = new File("test");
File jarPack = new File("packed_test.jar");
unpack(testJar, testDir);
jar(testDir, jarPack);
}
public static void jar(File directory, File zipfile) throws IOException {
URI base = directory.toURI();
Deque<File> queue = new LinkedList<>();
queue.push(directory);
OutputStream out = new FileOutputStream(zipfile);
Closeable res = out;
try {
ZipOutputStream zout = new ZipOutputStream(out);
res = zout;
while (!queue.isEmpty()) {
directory = queue.pop();
for (File kid : directory.listFiles()) {
String name = base.relativize(kid.toURI()).getPath();
if (kid.isDirectory()) {
queue.push(kid);
name = name.endsWith("/") ? name : name + "/";
zout.putNextEntry(new ZipEntry(name));
} else {
zout.putNextEntry(new ZipEntry(name));
copy(kid, zout);
zout.closeEntry();
}
}
}
} finally {
res.close();
}
}
private static void copy(File file, OutputStream out) throws IOException {
try (InputStream in = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
while (true) {
int readCount = in.read(buffer);
if (readCount < 0) {
break;
}
out.write(buffer, 0, readCount);
}
}
}
public static void unpack(File zip, File extractTo) throws IOException {
ZipFile archive = new ZipFile(zip);
Enumeration e = archive.entries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
File file = new File(extractTo, entry.getName());
if (entry.isDirectory() && !file.exists()) {
file.mkdirs();
} else {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
BufferedOutputStream out;
try (InputStream in = archive.getInputStream(entry)) {
out = new BufferedOutputStream(
new FileOutputStream(file));
byte[] buffer = new byte[8192];
int read;
while (-1 != (read = in.read(buffer))) {
out.write(buffer, 0, read);
}
}
out.close();
}
}
}
}