1

私はいくつかのjar-updateスニペットをデバッグしていて、もう一方を逆にする必要があるzip / unzipの組み合わせに出くわしましたが、jarで試してみると、すべてのファイルが存在していても失敗しました。誰かがこれがどこで間違っているのか理解できますか?

SSCCE(コンパイルする必要はありません):ここからダウンロードしてください!

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」と「抽出するバージョン」の値が異なります。それがどれほど重要かはわかりませんが。

4

1 に答える 1

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();
            }
        }
    }
}

私が見つけたこの質問のおかげで:) java.util.zip - ディレクトリ構造の再作成

于 2012-07-27T19:36:30.930 に答える