簡體   English   中英

將.jar文件提取到目錄中,添加新文件,然后重新打包為Java中的.jar文件

[英]Extracting .jar files to a directory, adding new files, then repacking into a .jar file in java

我想知道是否有辦法采用JFileChooser選擇給定的.jar文件,將其解壓縮並放入新目錄中。 然后,從另一個目錄中獲取所有文件,將其添加到包含解壓縮的.jar文件的目錄中,然后進行所有處理並將其重新打包。

我這樣做是因為我想要一種非常簡單的方法來為該游戲安裝minecraft的mod,您可以在其中選擇minecraft.jar,並確保該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?
    }
}

如您所見,我不知道自己在做什么。 我確實知道需要什么進口,但是僅此而已。 幫助將不勝感激,對我做錯的任何事情發怨言會使我生氣。 謝謝!

編輯:如果您知道一種獲得相同結果的方法,而不是我一直在尋找的方法,請讓我知道如何做。 只要得到想要的結果,那就太好了。 再次感謝!

這個想法相對簡單。 您有一些陷阱(例如如果文件已經存在該怎么辦以及類似的事情),但是否則...

我先來看一下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) {
            }

        }

    }
}

您可以使用這個非常簡單的庫來打包/解壓縮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>

使用鏈接下面的鏈接檢查最新版本以使用最新依賴

如果發現一些錯誤,請使用我的公共問題跟蹤器

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM