`

从JAR和zip档案文件中提取Java 资源

 
阅读更多

多数 java 程序员都非常清楚使用 jar 文件将组成 java 解决方案的各种资源(即 .class 文件、声音和图像)打包的优点。刚开始使用 jar 文件的人常问的一个问题是:“如何从 jar 文件中提取图像呢?”本文将回答这个问题,并会提供一个类,这个类使从 jar 文件中提取任何资源变得非常简单!

加载 gif 图像
假定我们有一个 jar 文件,其中包含我们的应用程序要使用的一组 .gif 图像。下面就是使用 JarResources 访问 jar 文件中的图像文件的方法:
JarResources JR=new JarResources("GifBundle.jar");

Image logo=Toolkit.getDefaultToolkit().createImage(JR.getResources("logo.gif"));

这段代码说明我们可以创建一个JarResources对象,并将其初始化为包含我们要使用的资源的 jar 文件 -- images.jar。随后我们使用JarResourcesgetResource()方法将来自 logo.gif 文件的原始数据提供给 awt Toolkit createImage()方法。
命名说明
JarResource
是一个非常简单的示例,它说明了如何使用 java 所提供的各种功能来处理 jar zip 档案文件。

工作方式
JarReources类的重要数据域用来跟踪和存储指定 jar 文件的内容:
public final class JarResources {

public boolean debugon=false;

private Hashtable htsizes=new Hashtable();
private Hashtable htjarcontents=new Hashtable();

private String jarfilename;

这样,该类的实例化设置 jar 文件的名称,然后转到init()方法完成全部实际工作。
public JarResources(String jarfilename) {
this.jarfilename=jarfilename;
init();
}

现在,init()方法只将指定 jar 文件的整个内容加载到一个 hashtable(通过资源名访问)中。

这是一个相当有用的方法,下面我们对它作进一步的分析。ZipFile类为我们提供了对 jar/zip 档案头信息的基本访问方法。这类似于文件系统中的目录信息。下面我们列出ZipFile中的所有条目,并用档案中每个资源的大小添充 htsizes hashtable
private void init() {
 try {
 // extracts just sizes only. 
ZipFile zf=new ZipFile(jarFileName);
 Enumeration e=zf.entries();
 while (e.hasMoreElements()) {
 ZipEntry ze=(ZipEntry)e.nextElement();
 if (debugOn) {
 System.out.println(dumpZipEntry(ze));
 }
 htSizes.put(ze.getName(),new Integer((int)ze.getSize()));
 }
 zf.close();
接下来,我们使用ZipInputStream类访问档案。ZipInputStream类完成了全部魔术,允许我们单独读取档案中的每个资源。我们从档案中读取组成每个资源的精确字节数,并将其存储在 htjarcontents hashtable 中,您可以通过资源名访问这些数据:
 // extract resources and put them into the hashtable.
 FileInputStream fis=new FileInputStream(jarFileName);
 BufferedInputStream bis=new BufferedInputStream(fis);
 ZipInputStream zis=new ZipInputStream(bis);
 ZipEntry ze=null;
 while ((ze=zis.getNextEntry())!=null) {
 if (ze.isDirectory()) {
 continue;////啊哟!没有处理子目录中的资源啊
 }
 if (debugOn) {
 System.out.println(
 "ze.getName()="+ze.getName()+","+"getSize()="+ze.getSize()
 );
 }
 int size=(int)ze.getSize();
 // -1 means unknown size. 
if (size==-1) {
 size=((Integer)htSizes.get(ze.getName())).intValue();
 }
 byte[] b=new byte[(int)size];
 int rb=0;
 int chunk=0;
while (((int)size - rb) > 0) {
 chunk=zis.read(b,rb,(int)size - rb);
 if (chunk==-1) {
 break;
 }
 rb+=chunk;
 }
 // add to internal resource hashtable
 htJarContents.put(ze.getName(),b);
 if (debugOn) {
 System.out.println(
 ze.getName()+"rb="+rb+
 ",size="+size+
 ",csize="+ze.getCompressedSize()
 );
 }
 }
 } catch (NullPointerException e) {
 System.out.println("done.");
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
请注意,用来标识每个资源的名称是档案中资源的限定路径名,例如,不是包中的类名 -- java.util.zip 包中的ZipEntry类将被命名为 "java/util/zip/ZipEntry",而不是 "java.util.zip.ZipEntry"

其它方法:
 /**
 * Dumps a zip entry into a string.
 * @param ze a ZipEntry
 */
 private String dumpZipEntry(ZipEntry ze) {
 StringBuffer sb=new StringBuffer();
 if (ze.isDirectory()) {
 sb.append("d "); 
} else {
 sb.append("f "); 
}
 if (ze.getMethod()==ZipEntry.STORED) {
 sb.append("stored "); 
} else {
 sb.append("defalted ");
 }
 sb.append(ze.getName());
 sb.append("/t");
 sb.append(""+ze.getSize());
 if (ze.getMethod()==ZipEntry.DEFLATED) {
 sb.append("/"+ze.getCompressedSize());
 }
 return (sb.toString());
 }

/**
 * Extracts a jar resource as a blob.
 * @param name a resource name.
 */
 public byte[] getResource(String name) {
 return (byte[])htJarContents.get(name);
 }
 
代码的最后一个重要部分是简单的测试驱动程序。该测试驱动程序是一个简单的应用程序,它接收 jar/zip 档案名和资源名。它试图发现档案中的资源文件,然后将成功或失败的消息报告出来:
public static void main(String[] args) throws IOException {
 if (args.length!=2) {
 System.err.println(
 "usage: java JarResources < jar file name> < resource name>"
 );
 System.exit(1);
 }
 JarResources jr=new JarResources(args[0]);
 byte[] buff=jr.getResource(args[1]);
 if (buff==null) {
 System.out.println("Could not find "+args[1]+".");
 } else {
 System.out.println("Found "+args[1]+ " (length="+buff.length+").");
 }
 }
} // End of JarResources class.
您已了解了这个类。一个易于使用的类,它隐藏了使用打包在 jar 文件中的资源的全部棘手问题。
小结
如果您曾经渴望知道如何从 jar 文件中提取图像,那么您现在已学到了一种方法。有了本技巧提供的这个新类,您就不仅可以用 jar 文件处理图像,而且可以将提取魔术用于 jar 文件中的任何资源。
分享到:
评论

相关推荐

    zip4j.jar包下载 包含zip4j-2.9.0版本和zip4j-1.3.1版本的j两个jar包,亲试均可用

    从zip文件中创建、添加、提取、更新和删除文件 支持流(ZipInputStream和ZipOutStream) 读/写受密码保护的zip文件和流 支持AES和zip标准加密方法 支持Zip64格式 存储(无压缩)和放气压缩方法 从拆分的zip文件中...

    zip4j-1.3.2.jar 包下载,处理zip压缩文件的开发包

    1.读/写受密码保护的Zip文件 2.创建,添加,提取,更新,从Zip文件中删除文件

    word提取文字以及所需jar.zip

    java开发过程中,word文档文字提取所需要的jar包,可以提取word中文字,以及可以调用其他相关的poi,对应的api可以去相应官网学习和查询。

    JAVA上百实例源码以及开源项目

    Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板  使用Java语言编写的一款用于反映颜色变化的面板,也就是大家...

    jargo:从 Go 访问 Java JAR 文件信息

    *JarInfo)GetJarInfo 从 Java JAR 文件中提取各种信息: 它提取清单(如 GetManifest) 它提取 JAR 文件中的文件名数组它返回一个指向 JarInfo 结构的指针: type JarInfo struct {*ManifestFiles []string}##

    java源码包---java 源码 大量 实例

    Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板  使用Java语言编写的一款用于反映颜色变化的面板,也就是大家...

    JAVA_API1.6文档(中文)

    java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供...

    SQLite JDBC 驱动程序在Java中访问和创建SQLite数据库文件的库完整项目源代码.zip

    SQLite JDBC是一个用于在Java中访问和创建SQLite数据库文件的库。我们的SQLiteJDBC库不需要配置,因为主要操作系统的本机库,包括Windows,Mac OS X,Linux等,被组装成一个JAR(Java Archive)文件。用法非常简单;...

    基于java的自动提取PDF论文文章标题作为该PDF的文件名源码+项目说明.zip

    基于java的自动提取PDF论文文章标题作为该PDF的文件名源码+项目说明.zip 本软件原是王炳宁先生公开在他的[主页](https://bingning.wang/research/Article/?id=114)上,本人偶遇之,遂常用。但发现它有一个bug,很多...

    JAVA上百实例源码以及开源项目源代码

    Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板  使用Java语言编写的一款用于反映颜色变化的面板,也就是大家...

    java源码包2

    Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板  使用Java语言编写的一款用于反映颜色变化的面板,也就是...

    java源码包4

    Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板  使用Java语言编写的一款用于反映颜色变化的面板,也就是...

    java源码包3

    Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板  使用Java语言编写的一款用于反映颜色变化的面板,也就是...

    StegoShare.jar.zip

    一个小工具,可以隐藏文件到某文件中,也可以从某文件中提取该文件

    Java解压ipa包,解压iphone游戏或者软件包

    java 技术交流群【52815036】,j2SE,J2ME,J2EE,Android,java范围技术交流,iso ...这个解包需要下载共享的org.apache.tools.zip.*需要的jar包,和Java把plist转成xml,备份shsh文件所需的jar包,如果不会加群Q我!

    一个java正则表达式工具类源代码.zip(内含Regexp.java文件)

    * [a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction) [a-z&&[^bc]] 从a 到 z, 但 b 和 c 除外: [ad-z] (子集) * [a-z&&[^m-p]] a through z, and not m through p: [a-lq-z](subtraction...

    Java 1.6 API 中文 New

    java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供允许 ...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java从网络取得文件 1个目标文件 简单 Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板 使用Java语言编写的一款...

    apktool+dex2jar+jd-gui.zip

    作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看 dex2jar 作用:将apk反编译成java源码(classes.dex转化成jar文件) jd-gui 作用:查看APK中classes.dex转化成出的jar文件,即源码文件

Global site tag (gtag.js) - Google Analytics