0

JFileChooserで選択された特定の.jarファイルを取得し、それを抽出して新しいディレクトリに配置する方法があるかどうか疑問に思っていました。次に、別のディレクトリからすべてのファイルを取得し、抽出された .jar ファイルを含むディレクトリに追加してから、すべてを取得して再度パッケージ化します。

私がこれを行っているのは、Minecraft.jar を選択するだけでそのゲームの mod をインストールする本当に簡単な方法が必要であり、mod のファイルがフォルダーにあることを確認し、少し待つためです。 JProgressBar によって示されます。

これは私がこれまで持っているすべてです

import java.io.*;
import java.util.jar.*;
import javax.swing.*;

public class Main extends JFrame {
    public Main() {
        super("Auto-mod installer");
        setSize(300, 60);
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JProgressBar bar = new JProgressBar(0, 100);
        add(bar);
        setVisible(true);
    }

    public static void main(String[] args) {
        Main m = new Main();
    }

    private void extract(File f) {
        //Hrm...
    }

    private void addModFiles() {
        //Uh...
    }

    private void repackage(File f) {
        //What?
    }
}

ご覧のとおり、私は自分が何をしているのかわかりません。必要なインポートが何であるかは知っていますが、それだけです。助けていただければ幸いです。私が間違ったことについて怒鳴ると、私は腹を立てます。ありがとう!

編集:同じ結果を得る方法を知っていて、それが私が探していた方法ではない場合は、その方法を教えてください。探していた結果が得られる限り、それは素晴らしいことです。再度、感謝します!

4

2 に答える 2

1

考え方は比較的単純です。いくつかの落とし穴があります (ファイルが既に存在する場合の対処方法など)、それ以外の場合は...

まず、 JarFileを見てみましょう。

(私は別の例の途中ですが、時間があればいくつか投稿します)

例による更新

public class JarTest {

    protected static final String OUTPUT_PATH = "..."; // The place you want to extact the jar to

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        new JarTest();

    }

    public JarTest() {

        try {

            unjar();
            // Copy new contents in...
            jar();

        } catch (IOException exp) {

            exp.printStackTrace();

        }

    }

    // This just recursivly lists through all the files to be included in the new jar
    // We don't care about the directories, as we will create them from the file
    // references in the Jar ourselves
    protected List<File> getFiles(File path) {

        List<File> lstFiles = new ArrayList<File>(25);

        // If you want the directories, add the "path" to the list now...

        File[] files = path.listFiles();
        if (files != null && files.length > 0) {

            for (File file : files) {

                if (file.isDirectory()) {

                    lstFiles.addAll(getFiles(file));

                } else {

                    lstFiles.add(file);

                }

            }

        }


        return lstFiles;

    }

    // Re-Jar the contents
    // You should always attempt to jar back to a new file, as you may not want to effect the original ;)
    public void jar() throws IOException {

        JarOutputStream jos = null;

        try {

            String outputPath = OUTPUT_PATH;

            // Create a new JarOutputStream to the file you want to create
            jos = new JarOutputStream(new FileOutputStream("...")); // Add your file reference

            List<File> fileList = getFiles(new File(OUTPUT_PATH));
            System.out.println("Jaring " + fileList.size() + " files");

            // Okay, I cheat.  I make a list of all the paths already added to the Jar only create
            // them when I need to.  You could use "file.isDirectory", but that would mean you would need
            // to ensure that the files were sorted to allow all the directories to be first
            // or make sure that the directory reference is added to the start of each recursion list
            List<String> lstPaths = new ArrayList<String>(25);
            for (File file : fileList) {

                // Replace the Windows file seperator
                // We only want the path to this element
                String path = file.getParent().replace("\\", "/");
                // Get the name of the file
                String name = file.getName();

                // Remove the output path from the start of the path
                path = path.substring(outputPath.length());
                // Remove the leading slash if it exists
                if (path.startsWith("/")) {

                    path = path.substring(1);

                }

                // Add the path path reference to the Jar
                // A JarEntry is considered to be a directory if it ends with "/"
                if (path.length() > 0) {

                    // At the trailing path seperator
                    path += "/";

                    // Check to see if we've already added it out not
                    if (!lstPaths.contains(path)) {

                        // At the path entry...we need need this to make it easier to 
                        // extract the files at a later state. There is a way to cheat,
                        // but I'll let you figure it out
                        JarEntry entry = new JarEntry(path);
                        jos.putNextEntry(entry);
                        jos.closeEntry();

                        // Make sure we don't try to add the same path entry again
                        lstPaths.add(path);

                    }

                }

                System.out.println("Adding " + path + name);

                // Create the actual entry for this file
                JarEntry entry = new JarEntry(path + name);
                jos.putNextEntry(entry);

                // Write the entry to the file
                FileInputStream fis = null;
                try {

                    fis = new FileInputStream(file);
                    byte[] byteBuffer = new byte[1024];
                    int bytesRead = -1;
                    while ((bytesRead = fis.read(byteBuffer)) != -1) {

                        jos.write(byteBuffer, 0, bytesRead);

                    }

                    jos.flush();

                } finally {

                    try {
                        fis.close();
                    } catch (Exception e) {
                    }

                }

                jos.closeEntry();

            }

            jos.flush();

        } finally {

            try {
                jos.close();
            } catch (Exception e) {
            }

        }

    }

    public void unjar() throws IOException {

        JarFile jarFile = null;

        try {

            String outputPath = OUTPUT_PATH;
            File outputPathFile = new File(outputPath);
            // Make the output directories.
            // I'll leave it up to you to decide how best to deal with existing content ;)
            outputPathFile.mkdirs();

            // Create a new JarFile reference
            jarFile = new JarFile(new File("C:/hold/Java_Harmony.jar"));

            // Get a list of all the entries
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {

                // Get the next entry
                JarEntry entry = entries.nextElement();
                // Make a file reference
                File path = new File(outputPath + File.separator + entry.getName());
                if (entry.isDirectory()) {

                    // Make the directory structure if we can
                    if (!path.exists() && !path.mkdirs()) {

                        throw new IOException("Failed to create output path " + path);

                    }

                } else {

                    System.out.println("Extracting " + path);

                    // Extract the file from the Jar and write it to disk
                    InputStream is = null;
                    OutputStream os = null;
                    try {

                        is = jarFile.getInputStream(entry);
                        os = new FileOutputStream(path);

                        byte[] byteBuffer = new byte[1024];
                        int bytesRead = -1;
                        while ((bytesRead = is.read(byteBuffer)) != -1) {

                            os.write(byteBuffer, 0, bytesRead);

                        }

                        os.flush();

                    } finally {

                        try {
                            os.close();
                        } catch (Exception e) {
                        }

                        try {
                            is.close();
                        } catch (Exception e) {
                        }

                    }

                }

            }

        } finally {

            try {
                jarFile.close();
            } catch (Exception e) {
            }

        }

    }
}
于 2012-08-19T04:49:58.640 に答える
0

この非常に単純なライブラリを使用して、jar ファイルをパック/アンパックできます

JarManager

とてもシンプル

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import fr.stevecohen.jarmanager.JarPacker;
import fr.stevecohen.jarmanager.JarUnpacker;

public class MyClass {

    public void addFileToJar(String jarPath, String otherFilePath) {
        try {
            JarUnpacker jarUnpacker = new JarUnpacker();
            File myJar = new File("./myfile.jar");
            File otherFile = new File(otherFilePath);

            Path unpackDir = Files.createTempDirectory(myJar.getName()); //create a temp directory to extract your jar
            System.out.println("Unpacking in " + unpackDir.toString());
            jarUnpacker.unpack(jarPath, unpackDir.toString()); //extraxt all files contained in the jar in temp directory

            Files.copy(otherFile.toPath(), new File(unpackDir.toFile(), otherFile.getName()).toPath()); //copy your file

            JarPacker jarRepacker = new JarPacker();
            File newJar = new File("./maNewFile.jar");
            System.out.println("Packing jar in " + newJar.getAbsolutePath());
            jarRepacker.pack(unpackDir.toString(), newJar.getAbsolutePath()); //repack the jar with the new files inside
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Maven依存関係を使用することもできます

<dependency>
    <groupId>fr.stevecohen.jarmanager</groupId>
    <artifactId>JarManager</artifactId>
    <version>0.5.0</version>
</dependency>

私のリポジトリも必要です

<repository>
    <id>repo-reapersoon</id>
    <name>ReaperSoon's repo</name>
    <url>http://repo-maven.stevecohen.fr</url>
</repository>

最後の依存関係を使用するには、以下のリンクで最後のバージョンを確認してください

バグを見つけた場合は、私の公開課題トラッカーを使用してください

于 2015-09-20T16:56:34.190 に答える