Java对Jar文件的操作转

  原文地址:http://www.cnblogs.com/mailingfeng/archive/2012/04/24/2122160.html

  一些文件路径补充知识:

  URI uri = new URI("file:/D:/workspace-home/JavaDemo/conf/");

  File dirFile = new File(uri);

 

   String dirPath = System.getProperty("user.dir") + "\\conf";

   File dirFile = new File(dirPath);

  

  获取jar包中文件的方法,是不能使用上面的方法的。需要如下来获得,此处如果不以“/” 开头,会被当作相对于当前类所在的包类处理,自然无法找到。Jar包内的文件是无法用File读取的,只能用Stream的方式读取。

   URL clzURL = this.getClass().getResource("/conf/test.properties");  //clzURL = jar的磁盘路径 + ”!“ + conf/test.properties

   URL nullURL = this.getClass().getResource("conf/test.properties");

  InputStream is = this.getClass().getResourceAsStream("/conf/test.properties");

  Properties props = new Properties();

  props.load(is);

  获取jar包中的内容需要通过遍历JarFile下的JarEntry,参见下面的例子。

  

  例子程序:

  包含了使用JarOutputStream和JarFile来进行 jar包的、解压操作,实际使用中使用JarOutputStream或JarFile的一种即可。

package jdk.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

import org.apache.log4j.Logger;
import org.junit.Test;


public class Util_Jar_Test {

    Logger log = Logger.getLogger(this.getClass());
    
    //jar
    public void copyJar(File src , File des) throws FileNotFoundException, IOException{
        JarInputStream jarIn = new JarInputStream(new BufferedInputStream(new FileInputStream(src)));
        Manifest manifest = jarIn.getManifest();
        JarOutputStream jarOut = null;
        if(manifest == null){
            jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(des)));
        }else{
            jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(des)),manifest);
        }
         
        byte[] bytes = new byte[1024];
        while(true){
            //重点
            ZipEntry entry = jarIn.getNextJarEntry();
            if(entry == null)break;
            jarOut.putNextEntry(entry);
            
            int len = jarIn.read(bytes, 0, bytes.length);
            while(len != -1){
                jarOut.write(bytes, 0, len);
                len = jarIn.read(bytes, 0, bytes.length);
            }
            log.info("Copyed: " + entry.getName());
//            jarIn.closeEntry();
//            jarOut.closeEntry();
            String a = new String();
            a.length();
        }
        jarIn.close();
        jarOut.finish();
        jarOut.close();
    }
    
    //解压jar
    public void unJar(File src , File desDir) throws FileNotFoundException, IOException{
        JarInputStream jarIn = new JarInputStream(new BufferedInputStream(new FileInputStream(src)));
        if(!desDir.exists())desDir.mkdirs();
        byte[] bytes = new byte[1024];
        
        while(true){
            ZipEntry entry = jarIn.getNextJarEntry();
            if(entry == null)break;
            
            File desTemp = new File(desDir.getAbsoluteFile() + File.separator + entry.getName());
            
            if(entry.isDirectory()){    //jar条目是空目录
                if(!desTemp.exists())desTemp.mkdirs();
                log.info("MakeDir: " + entry.getName());
            }else{    //jar条目是文件
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(desTemp));
                int len = jarIn.read(bytes, 0, bytes.length);
                while(len != -1){
                    out.write(bytes, 0, len);
                    len = jarIn.read(bytes, 0, bytes.length);
                }
                
                out.flush();
                out.close();
                
                log.info("Copyed: " + entry.getName());
            }
            jarIn.closeEntry();
        }
        
        //解压Manifest文件
        Manifest manifest = jarIn.getManifest();
        if(manifest != null){
        File manifestFile = new File(desDir.getAbsoluteFile()+File.separator+JarFile.MANIFEST_NAME);
        if(!manifestFile.getParentFile().exists())manifestFile.getParentFile().mkdirs();
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(manifestFile));
        manifest.write(out);
        out.close();
        }
        
        //关闭JarInputStream
        jarIn.close();
    }
    
    
    //jar by JarFile
    public void copyJarByJarFile(File src , File des) throws IOException{
        //重点
        JarFile jarFile = new JarFile(src);
        Enumeration<JarEntry> jarEntrys = jarFile.entries();
        JarOutputStream jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(des)));
        byte[] bytes = new byte[1024];
        
        while(jarEntrys.hasMoreElements()){
            JarEntry entryTemp = jarEntrys.nextElement();
            jarOut.putNextEntry(entryTemp);
            BufferedInputStream in = new BufferedInputStream(jarFile.getInputStream(entryTemp));
            int len = in.read(bytes, 0, bytes.length);
            while(len != -1){
                jarOut.write(bytes, 0, len);
                len = in.read(bytes, 0, bytes.length);
            }
            in.close();
            jarOut.closeEntry();
            log.info("Copyed: " + entryTemp.getName());
        }
        
        jarOut.finish();
        jarOut.close();
        jarFile.close();
    }
    
    //解压jar文件by JarFile
    public void unJarByJarFile(File src , File desDir) throws FileNotFoundException, IOException{
        JarFile jarFile = new JarFile(src);
        Enumeration<JarEntry> jarEntrys = jarFile.entries();
        if(!desDir.exists())desDir.mkdirs(); //建立用户指定存放的目录
        byte[] bytes = new byte[1024];    
        
        while(jarEntrys.hasMoreElements()){
            ZipEntry entryTemp = jarEntrys.nextElement();
            File desTemp = new File(desDir.getAbsoluteFile() + File.separator + entryTemp.getName());
            
            if(entryTemp.isDirectory()){    //jar条目是空目录
                if(!desTemp.exists())desTemp.mkdirs();
                log.info("makeDir" + entryTemp.getName());
            }else{    //jar条目是文件
                //因为manifest的Entry是"META-INF/MANIFEST.MF",写出会报"FileNotFoundException"
                File desTempParent = desTemp.getParentFile();
                if(!desTempParent.exists())desTempParent.mkdirs();
                
                BufferedInputStream in = new BufferedInputStream(jarFile.getInputStream(entryTemp));
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(desTemp));
                
                int len = in.read(bytes, 0, bytes.length);
                while(len != -1){
                    out.write(bytes, 0, len);
                    len = in.read(bytes, 0, bytes.length);
                }
                
                in.close();
                out.flush();
                out.close();
                
                log.info("Copyed: " + entryTemp.getName());
            }
        }
        
        jarFile.close();
    }
    
    
    
    /*实验结论:
     * 1.JarInputStream的getNextJarEntry()和jarOutputStream的putNextJarEntry()中没有包括"META-INF/MANIFEST.MF"这一项,因此和解压都    要注意
     * 2.JarFile的entries()方法包含了全部Entry,也包括"META-INF/MANIFEST.MF",没有"META-INF/"这一项,因此在解压的时候要先检测父文件存不存在
     * 4.jar文件有3中方法, A是直接用BufferedInputStream和BufferedOutputStream,
     *                      B是用JarInputStream的getNextJarEntry()和jarOutputStream的putNextJarEntry()
     *                      C是用JarFile的entries()方法,遍寻JarEntry的InputStream,以此写出
     * 5.解压jar的话推荐使用JarFile,当前实例方法只支持解压jar文件
     * 6.在的时候,src文件只可以是jar文件,但des文件可以是带zip或rar后缀的文件
     */
    
    @Test
    public void testCopyJar(){
        File src = new File("C:/a.jar");
        File des = new File("C:/testCopy.jar");
        //实验表明只运行和解压jar文件
//        File src = new File("C:/rtf.zip");
//        File des = new File("C:/testCopy.zip");
        try {
            copyJar(src,des);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    @Test
    public void testUnJar(){
        File src = new File("C:/a.jar");
//        File src = new File("C:/b.rar");    //不支持rar解压
        String desFile = "aa";
        File desDir = new File(src.getParent()+File.separator+desFile);
        try {
            unJar(src, desDir);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
    @Test
    public void testCopyJarByJarFile(){
        File src = new File("C:/a.jar");
        File des = new File("C:/testCopy.zip");
        try {
            copyJarByJarFile(src,des);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    @Test
    public void testUnJarByJarFile(){
        File src = new File("C:/a.jar");
//        File src = new File("C:/b.rar");    //不支持rar解压
        String desFile = "aa";
        File desDir = new File(src.getParent()+File.separator+desFile);
        try {
            unJarByJarFile(src, desDir);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 }

 

更多相关文章
  • 1.openSession是直接创建一个session,getCurrentSession是获取当前线程池中的session. 2.session是存放在ThreadLocal中,不会有安全性问题,因为每个线程只能访问到当前线程对应的session. 3.getCurrentSession的效率更高 ...
  • 苹果发布了最新iOS9系统,修改了旧版本中的一些BUG,很多朋友都想体验下最新的iOS9系统,而iOS9如何刷机?怎样在不需要开发者账号直接刷机呢?下面小编为大家图文介绍下,希望可以帮助到大家 本文介绍的刷机教程通用于使用爱思助手进行所有iOS 设备刷机,只需要下载不同的固件就可以了 软件名称:爱思 ...
  • 如果你认为苹果Mac比Windows系统更安全,请三思.研究人员已经证明了:这不是真的. Mac不再“百毒不侵” 两名研究人员开发出第一个可感染Mac的固件蠕虫病毒,并且可以在无需联网的情况下在MacBook间进行自动传播. 该病毒被称为“Thunderstrike 2”,是年初“Thunderst ...
  • 一.主要知识点: 1. Iptables表链结构 2. 数据包过滤流程 3. Iptables书写规则 4. Iptables条件匹配 5. Iptables数据包控制 6. Iptables七层过滤 7. Iptables脚本 二.具体的知识点介绍 1. Iptables表链结构 1)默认的4个规 ...
  • 关于API的设计与实现 API的设计是软件开发中一个独特的领域.最主要的特殊点在于API是供开发者使用的界面,即Application Programmer Interfaces.类似于用户可以直接使用到的GUI的作用一样.所以相对于依据软件设计的原则,考虑用户的"体验"会更加重 ...
  • 现实:PC.笔记本都通过网线接在局域网内,局域网无法上网:笔记本有无线网卡,可连WIFI上网. 现在想让PC通过笔记本来共享上网. 步骤: 1.笔记本开启DHCP.方法是开启"服务"里的dhcp client. 2.打开笔记本的网络和共享中心-更改适配器配置,右击无线网络,属性, ...
一周排行
  • 用VC做界面难免会遇到要用图片做界面,但VC6显示透明PNG还是非常费劲的,本文向大家介绍如何用CxImage类实现Static控件显示透明PNG1.创建一基于对话框的MFC工程2.新建类CMyStatic继承CSt ...
  • 代理模式 定义: 为其他对象提供一种代理以控制这个对象的访问. 适用性: 在需要比较通用和复杂的对象指针代替简单的指针的时候,需要使用代理模式.以下是几种常见的情况: 1. 远程代理,为一个对象在不同的地址空间提供局 ...
  • 通配符与正则表达式中的某些符号有些类似,但二者是完全无关的,不要混淆了.   符号 意义 * 代表0到无穷多个任意字符 ? 代表某一个任意字符 [abcd] 代表a,b,c,d中的任何一个字符 [] 代表0到9 ...
  • 免费的WIFI热点信号寻找 目前有很多地方都有免费的WIFI热点信号,但如何找到这些信号成为了漂流在外网友们的难题,那么文章接下来的目的就是要告诉你,到底该如何寻找“热点”?你身边哪里的免费“热点”信号速度快信号好? ...
  • 今天看到了一个题目,需要输入一个数字,表示成绩和他的成绩的级别: A: 90--100 B: 80--89 C: 70--79 D: 60--69 E: < 60 需求在上面大家都看到了,加入输入00之 ...
  • 昨天编程遇到一个问题两个类字段都是二十多个,其中有十多个是相同的,需要将一个类的字段赋值给另外一个类,开始的自己想手动的一个个去赋值,后来想来一下C#基础知识,用PropertyInfo就可以解决类似的问题,博客园写 ...
  • FRG图像文件格式(二):压缩质量 作者: [email protected]   2013.06.10 FRG是一种优化从磁盘加载和解码到显示需要的时间的图像文件格式.(更多介绍:http://blog.csd ...
  • 扫描器是一类自动检测本地或远程主机安全弱点的程序,它能够快速的准确的发现扫描目标存在的漏洞并提供给使用者扫描结果.工作原理是扫描器向目标计算机发送数据包,然后根据对方反馈的信息来判断对方的操作系统类型.开发端口.提供 ...
  • 我已经深深厌恶在多个测试博客网站来回切换看各种文章了,不知道你是否也是如此呢?所以我研究了一下开源爬虫WebCollector,并对其进行了改造以满足我的需求,可以轻松添加站点来爬取其页面内容,以后再也不会漏掉一篇优 ...
  • 多维数组和广义表是一种复杂的非线性结构,它们的逻辑特征是:一个数据元素可能有多个直接前驱和多个直接后继. 多维数组 1.数组(向量)--常用数据类型     一维数组(向量)是存储于计算机的连续存储空间中的多个具有统 ...