[英]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文件
很簡單
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.