前段时间,我想找一个能在程序中直接更改Jar文件的办法,却一直没找到。只是找到了这种办法。翻译过来,和大家共享。
我 们知道,用ZIP,jar可以将多个文件一起打包,如classes,images etc. 其实我们可以用J2SE的SDK提供的Jar命令来创建 Jar文件,尽管我们可以通过该命令添加一个文件到Jar包中,但我们没有很直接的办法在程序中这么做,也没有办法通过Jar命令在Jar中删除一个或多 个文件,
下面我们来研究一下如何更新一个Jar:要更新一个Jar,你必须创建原Jar文件的一个拷贝,在我们更新完拷贝后移除原文件, 然后将拷贝重命名为原文件名就可以了。(译者注:我曾经试图找过更直接的办法,但是徒劳。只是找到这篇文章的原文) 对于添加一个或多个文件,删除一个或 多个文件,思路应该是一样的。我们将举例更新一个Jar文件。
首先我们应该知道如何列出Jar文件中的Entries:
然后我们要知道如何写入Jar文件
这里的输出是一个JarOutputStream
在确定更新成功时,我们不要忘记删除原文件,并重新命名临时文件。
下边我们将给出完整的代码:
我 们知道,用ZIP,jar可以将多个文件一起打包,如classes,images etc. 其实我们可以用J2SE的SDK提供的Jar命令来创建 Jar文件,尽管我们可以通过该命令添加一个文件到Jar包中,但我们没有很直接的办法在程序中这么做,也没有办法通过Jar命令在Jar中删除一个或多 个文件,
下面我们来研究一下如何更新一个Jar:要更新一个Jar,你必须创建原Jar文件的一个拷贝,在我们更新完拷贝后移除原文件, 然后将拷贝重命名为原文件名就可以了。(译者注:我曾经试图找过更直接的办法,但是徒劳。只是找到这篇文章的原文) 对于添加一个或多个文件,删除一个或 多个文件,思路应该是一样的。我们将举例更新一个Jar文件。
首先我们应该知道如何列出Jar文件中的Entries:
- JarFile jar = new JarFile(name);
- Enumeration e = jar.entries();
- while (e.hasMoreElements()) {
- System.out.println("/t" + entry.getName());
- }
然后我们要知道如何写入Jar文件
- while (entries.hasMoreElements()) {
- JarEntry entry = (JarEntry) entries.nextElement();
- InputStream is = jar.getInputStream(entry);
- newJar.putNextEntry(entry);
- while ((bytesRead = is.read(buffer)) != -1) {
- newJar.write(buffer, 0, bytesRead);
- }
- }
这里的输出是一个JarOutputStream
- File tempJar = File.createTempFile(nameOfJar, null);
- JarOutputStream newJar = new JarOutputStream(
- new FileOutputStream(tempJar));
在确定更新成功时,我们不要忘记删除原文件,并重新命名临时文件。
- if (success) {
- File origFile = new File(nameOfJar);
- origFile.delete();
- tempJar.renameTo(origFile);
- }
下边我们将给出完整的代码:
- import java.io.*;
- import java.util.*;
- import java.util.zip.*;
- import java.util.jar.*;
- public class AddFileToJar {
- public static void main(String args[]) {
- if (args.length != 2) {
- System.err.println(
- "command: java AddFileToJar example.jar filetoadd.txt");
- System.exit(-1);
- }
- String nameOfJar = args[0];
- String nameToAdd = args[1];
- File tempJar = null;
- try {
- tempJar = File.createTempFile(nameOfJar, null);
- } catch (IOException e) {
- System.err.println("Unable to create intermediate file.");
- System.exit(-2);
- }
- JarFile jar = null;
- try {
- jar = new JarFile(nameOfJar);
- } catch (IOException e) {
- System.err.println("Unable to access original file.");
- System.exit(-3);
- }
- // Only rename file at end on success
- boolean success = false;
- try {
- JarOutputStream newJar =
- new JarOutputStream(
- new FileOutputStream(tempJar));
- byte buffer[] = new byte[1024];
- int bytesRead;
- try {
- FileInputStream fis = new FileInputStream(nameToAdd);
- // Add back the original files
- Enumeration entries = jar.entries();
- while (entries.hasMoreElements()) {
- // Prompt for copy
- JarEntry entry = (JarEntry) entries.nextElement();
- String name = entry.getName();
- System.out.println
- ("Copy " + name + " into new jar? (y or n)");
- BufferedReader reader =
- new BufferedReader
- (new InputStreamReader(System.in));
- String line = reader.readLine();
- if ("n".equals(line)) {
- // if user enters n, don't copy file,
- // move to next name
- System.out.println("Skipping: " + name);
- continue;
- }
- InputStream is = jar.getInputStream(entry);
- newJar.putNextEntry(entry);
- while ((bytesRead = is.read(buffer)) != -1) {
- newJar.write(buffer, 0, bytesRead);
- }
- }
- // Add new file last
- try {
- JarEntry entry = new JarEntry(nameToAdd);
- newJar.putNextEntry(entry);
- while ((bytesRead = fis.read(buffer)) != -1) {
- newJar.write(buffer, 0, bytesRead);
- }
- } finally {
- fis.close();
- }
- success = true;
- } catch (IOException ex) {
- System.err.println
- ("Operation aborted due to : " + ex);
- } finally {
- try {
- newJar.close();
- } catch (IOException ignored) {
- }
- }
- } catch (IOException ex) {
- System.err.println(
- "Can't access new file");
- } finally {
- try {
- jar.close();
- } catch (IOException ignored) {
- }
- if (!success) {
- tempJar.delete();
- }
- }
- if (success) {
- File origFile = new File(nameOfJar);
- origFile.delete();
- tempJar.renameTo(origFile);
- }
- }
- }