在程序中更新JAR文件

前段时间,我想找一个能在程序中直接更改Jar文件的办法,却一直没找到。只是找到了这种办法。翻译过来,和大家共享。

我 们知道,用ZIP,jar可以将多个文件一起打包,如classes,images etc. 其实我们可以用J2SE的SDK提供的Jar命令来创建 Jar文件,尽管我们可以通过该命令添加一个文件到Jar包中,但我们没有很直接的办法在程序中这么做,也没有办法通过Jar命令在Jar中删除一个或多 个文件,

下面我们来研究一下如何更新一个Jar:要更新一个Jar,你必须创建原Jar文件的一个拷贝,在我们更新完拷贝后移除原文件, 然后将拷贝重命名为原文件名就可以了。(译者注:我曾经试图找过更直接的办法,但是徒劳。只是找到这篇文章的原文) 对于添加一个或多个文件,删除一个或 多个文件,思路应该是一样的。我们将举例更新一个Jar文件。

首先我们应该知道如何列出Jar文件中的Entries:
  1.  JarFile jar = new JarFile(name);
  2.        Enumeration e = jar.entries();
  3.        while (e.hasMoreElements()) {
  4.          System.out.println("/t" + entry.getName());      
  5.        } 

然后我们要知道如何写入Jar文件

  1. while (entries.hasMoreElements()) {
  2.          JarEntry entry = (JarEntry) entries.nextElement();
  3.          InputStream is = jar.getInputStream(entry);
  4.          newJar.putNextEntry(entry);
  5.          while ((bytesRead = is.read(buffer)) != -1) {
  6.                newJar.write(buffer, 0, bytesRead);
  7.          }
  8.       }

 
这里的输出是一个JarOutputStream

  1.     File tempJar = File.createTempFile(nameOfJar, null);
  2.          JarOutputStream newJar = new JarOutputStream(
  3.          new FileOutputStream(tempJar));

 
在确定更新成功时,我们不要忘记删除原文件,并重新命名临时文件。

  1. if (success) {
  2.         File origFile = new File(nameOfJar);
  3.         origFile.delete();
  4.         tempJar.renameTo(origFile);
  5.       }


下边我们将给出完整的代码:
  1.  import java.io.*;
  2.    import java.util.*;
  3.    import java.util.zip.*;
  4.    import java.util.jar.*;
  5.    
  6.    public class AddFileToJar {
  7.    
  8.      public static void main(String args[]) {
  9.        if (args.length != 2) {
  10.          System.err.println(
  11.            "command: java AddFileToJar example.jar filetoadd.txt");
  12.          System.exit(-1);
  13.        }
  14.    
  15.        String nameOfJar = args[0];
  16.        String nameToAdd = args[1];
  17.    
  18.        File tempJar = null;
  19.        try {
  20.          tempJar = File.createTempFile(nameOfJar, null);
  21.        } catch (IOException e) {
  22.          System.err.println("Unable to create intermediate file.");
  23.          System.exit(-2);
  24.        }
  25.    
  26.        JarFile jar = null;
  27.        try {
  28.          jar = new JarFile(nameOfJar);
  29.        } catch (IOException e) {
  30.          System.err.println("Unable to access original file.");
  31.          System.exit(-3);
  32.        }
  33.    
  34.        // Only rename file at end on success
  35.        boolean success = false;
  36.    
  37.        try {
  38.    
  39.          JarOutputStream newJar =
  40.            new JarOutputStream(
  41.              new FileOutputStream(tempJar));
  42.    
  43.          byte buffer[] = new byte[1024];
  44.          int bytesRead;
  45.    
  46.          try {
  47.            FileInputStream fis = new FileInputStream(nameToAdd);
  48.    
  49.            // Add back the original files
  50.    
  51.            Enumeration entries = jar.entries();
  52.    
  53.            while (entries.hasMoreElements()) {
  54.              // Prompt for copy
  55.              JarEntry entry = (JarEntry) entries.nextElement();
  56.              String name = entry.getName();
  57.              System.out.println
  58.                ("Copy " + name + " into new jar? (y or n)");
  59.              BufferedReader reader = 
  60.                new BufferedReader
  61.                  (new InputStreamReader(System.in));
  62.              String line = reader.readLine();
  63.              if ("n".equals(line)) {
  64.                // if user enters n, don't copy file, 
  65.                // move to next name
  66.                System.out.println("Skipping: " + name);
  67.                continue;
  68.              }
  69.              InputStream is = jar.getInputStream(entry);
  70.              newJar.putNextEntry(entry);
  71.              while ((bytesRead = is.read(buffer)) != -1) {
  72.                newJar.write(buffer, 0, bytesRead);
  73.              }
  74.            }
  75.    
  76.            // Add new file last
  77.            try {
  78.              JarEntry entry = new JarEntry(nameToAdd);
  79.              newJar.putNextEntry(entry);
  80.    
  81.              while ((bytesRead = fis.read(buffer)) != -1) {
  82.                newJar.write(buffer, 0, bytesRead);
  83.              }
  84.            } finally {
  85.              fis.close();
  86.            }
  87.            success = true;
  88.          } catch (IOException ex) {
  89.            System.err.println
  90.              ("Operation aborted due to : " + ex);
  91.          } finally {
  92.            try {
  93.              newJar.close();
  94.            } catch (IOException ignored) {
  95.            }
  96.          }
  97.        } catch (IOException ex) {
  98.          System.err.println(
  99.            "Can't access new file");
  100.        } finally {
  101.          try {
  102.            jar.close();
  103.          } catch (IOException ignored) {
  104.          }
  105.    
  106.          if (!success) {
  107.            tempJar.delete();
  108.          }
  109.        }
  110.    
  111.        if (success) {
  112.          File origFile = new File(nameOfJar);
  113.          origFile.delete();
  114.          tempJar.renameTo(origFile);
  115.        }
  116.      }
  117.    }
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值