使用Java解包和重新打包jar会导致jar文件损坏

使用Java解包和重新打包jar会导致jar文件损坏,java,jar,io,compression,zip,Java,Jar,Io,Compression,Zip,我一直在调试一些jar更新片段,我遇到了一个zip/unzip组合,它应该与另一个相反,但是当我在jar上尝试它时,即使所有文件都存在,它也失败了。有人能找出哪里出了问题吗 SSCCE(无需编译): package-jarsscce; 导入java.io.*; 导入java.util.*; 导入java.util.jar.*; 导入java.util.zip.*; 公共类Jarscce{ 公共静态void main(字符串[]args)引发IOException{ File testJar=新文

我一直在调试一些jar更新片段,我遇到了一个zip/unzip组合,它应该与另一个相反,但是当我在jar上尝试它时,即使所有文件都存在,它也失败了。有人能找出哪里出了问题吗

SSCCE(无需编译):

package-jarsscce;
导入java.io.*;
导入java.util.*;
导入java.util.jar.*;
导入java.util.zip.*;
公共类Jarscce{
公共静态void main(字符串[]args)引发IOException{
File testJar=新文件(“test.jar”);
文件testDir=新文件(“测试”);
File jarPack=新文件(“packed_test.jar”);
解包(testJar、testDir);
jar(testDir,jarPack);
}
公共静态voidjar(文件目录,文件zip)引发IOException{
try(JarOutputStream jos=newjaroutputstream(newfileoutputstream(zip))){
jar(目录,目录,jos);
}
}
私有静态void jar(文件目录、文件基、JarOutputStream jos)抛出IOException{
File[]files=目录.listFiles();

byte[]buffer=new byte[1我想我已经发现了问题,在这个链接上有一个峰值:。它谈到使用
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();
            }
        }
    }
}
import java.io.*;
导入java.net.URI;
导入java.util.Deque;
导入java.util.Enumeration;
导入java.util.LinkedList;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipFile;
导入java.util.zip.ZipoutStream;
公共班机{
公共静态void main(字符串[]args)引发IOException{
File testJar=新文件(“test.jar”);
文件testDir=新文件(“测试”);
File jarPack=新文件(“packed_test.jar”);
解包(testJar、testDir);
jar(testDir,jarPack);
}
公共静态void jar(文件目录、文件zipfile)引发IOException{
URI base=directory.toURI();
Deque queue=new LinkedList();
push(目录);
OutputStream out=新文件OutputStream(zipfile);
可关闭的res=输出;
试一试{
ZipOutputStream zout=新ZipOutputStream(输出);
res=zout;
而(!queue.isEmpty()){
directory=queue.pop();
对于(文件kid:directory.listFiles()){
String name=base.relativize(kid.toURI()).getPath();
if(kid.isDirectory()){
排队。推(小孩);
name=name.endsWith(“/”)?name:name+“/”;
zout.putNextEntry(新ZipEntry(名称));
}否则{
zout.putNextEntry(新ZipEntry(名称));
复印件(孩子,佐特);
zout.closeEntry();
}
}
}
}最后{
res.close();
}
}
私有静态无效副本(文件、输出流输出)引发IOException{
try(InputStream in=新文件InputStream(文件)){
字节[]缓冲区=新字节[1024];
while(true){
int readCount=in.read(缓冲区);
如果(读取计数<0){
打破
}
out.write(缓冲区,0,读取计数);
}
}
}
公共静态void解包(文件zip、文件extractTo)引发IOException{
ZipFile存档=新ZipFile(zip);
枚举e=archive.entries();
而(e.hasMoreElements()){
ZipEntry条目=(ZipEntry)e.nextElement();
File File=新文件(extractTo,entry.getName());
if(entry.isDirectory()&&!file.exists()){
mkdirs()文件;
}否则{
如果(!file.getParentFile().exists()){
文件.getParentFile().mkdirs();
}
缓冲输出流输出;
try(InputStream in=archive.getInputStream(entry)){
out=新的BufferedOutputStream(
新文件输出流(文件));
字节[]缓冲区=新字节[8192];
int-read;
而(-1!=(read=in.read(buffer))){
输出。写入(缓冲区,0,读取);
}
}
out.close();
}
}
}
}

由于这个问题,我发现:)

它只是说jar文件无效或已损坏。这正是我的问题-我必须在使用
JarOutputStream
的包装中遗漏一些非常小的细节,这将允许创建的jar工作。这是一项如此简单的任务,让我很恼火,而我却在这里坐了好几个小时试图解决这个问题出来了。>.@paranoid android Lol我知道。看看文本编辑器中两个jar的输出……它们的格式差别很大。zip方法做了一些有趣的事情。我以前有一个相同类型的项目,现在正试图找到它的代码。很酷,谢谢,让我知道你能找到什么。我已经在谷歌上搜索了几个小时——真不敢相信我没有找到它在帖子中你链接了。虽然我刚刚有了一个想法,使用java jar工具创建了一个包装器,例如,
jar cf jarfile
等等。你是一个绝对的传奇,David!但是这确实让我想知道另一个zip方法出了什么问题?但是我喜欢这个,我想我会保留它。再次感谢+1@paranoid-安卓:)谢谢,很高兴老实说,这一定是它用来保存它的格式,也许是
JarOutputStream
影响了它?不过我不是100%肯定
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();
            }
        }
    }
}