精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Java>>源码收藏>>[转载]如何从JAR和ZIP包中析取Java源文件

主题:[转载]如何从JAR和ZIP包中析取Java源文件
发信人: consultant()
整理人: zjxyz(2002-01-26 13:57:56), 站内信件
如何从JAR和ZIP包中析取Java源文件
                                               录入/江湖小子
                                                 1999.08.07


摘 要: 

将Java 源 文 件 打 包 成JAR 文 件, 可 以 减 少 下 载 时、 增 强 安 全

 性 和 易 管 理 性。 本 文 将 讨 论 如 何 从JAR 文 件 中
提 取Java 源 文 件。 

绝 大 多 数Java 程 序 员 非 常 善 于 利 用JAR 文 件 的 优 势 将 各 种 

包 含Java 解 决 方 案 的 资 源 进 行 打 包。 面 对JAR 文
件, 人 们 询 问 的 一 个 普 遍 问 题 是:“ 我 何 从 一 个JAR 文 件 中

 提 取 出 一 个 图 象 文 件 ?”。 本 文 将 回 答 这 个
问 题, 并 且 提 供 一 个Java 类, 它 可 以 容 易 地 从 一 个JAR 文 件

 中 析 取 出 任 意 一 个 文 件。 

加 载 一 个GIF 文 件

假 设 我 们 有 一 个 包 含 一 些.GIF 图 象 文 件 的JAR 文 件, 这 些 图

 象 文 件 将 在 应 用 程 序 中 被 使 用。 以 下 是 我 们
使 用 JarResources 类 从JAR 文 件 中 析 取 一 个 图 象 文 件 的 代 码:

 

JarResources jar = new JarResources ("Images.jar"); 

Image logo = 

Toolkit.getDefaultToolkit().createImage (jar.getResource ("logo.gif");



上 面 代 码 的 含 义 是: 我 们 建 立 一 个JavaResources 对 象, 并 将

 它 初 始 化 为 一 个 包 含 我 们 感 兴 趣 资 源 的JAR 文
件 -- Images.jar。 然 后 我 们 使 用JavaResources 类 的getResource() 方

 法 从logo.gif 取 出 原 始 数 据, 然 后 调 用AWT 工 具
箱 的createImage() 方 法 从 原 始 数 据 建 立 一 个Image 对 象 实 例。

 

有 关 命 名 的 注 释

JarResource 是 一 个 相 当 容 易 理 解 的 例 子, 它 解 释 了 如 何 使

 用Java 1.1 提 供 的 各 种 功 能 处 理JAR 和ZIP 压 缩 文
档 文 件。 

关 于 命 名 的 的 简 单 解 释。Java 对 压 缩 文 档 的 支 持 实 际 上 起

 源 于 使 用 一 般 的ZIP 压 缩 文 档 格 式。 因 此,Java
中 实 现 压 缩 档 案 操 作 的 类 都 被 放 入java.util.zip 包 中; 这 些

 类 一 般 以“Zip .” 开 始。 但 是Java 升 级 到 了1.1
版 以 后, 压 缩 文 档 的 命 名 变 得 以Java 为 中 心 了。 从 此, 我 

们 所 说 的JAR 压 缩 文 档 基 本 上 还 是zip 文 件。 

代 码 具 体 的 工 作 流 程

JavaResources 类 中 的 一 些 重 要 字 段 用 来 跟 踪 和 存 储 指 定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) 中( 杂 凑 表 名 可 以 从 资 源 名 进 行
访 问) 

init() 是 一 个 功 能 相 当 强 大 的 方 法, 让 我 们 来 逐 步 理 解 它

 的 功 能。ZipFile 类 使 我 们 基 本 上 能 访 问JAR/Zip
压 缩 文 档 的 头 部 信 息。 这 和 一 个 文 件 系 统 的 目 录 信 息 相

 似。 在 这 里 我 们 列 出Zip 文 件 的 所 有 条 目
(entry), 并 且 按 照 文 档 中 的 每 个 资 源 的 尺 寸 创 建htSizes 杂

 凑 表(hashtable)。 

private void init() {


try {

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 类 访 问 压 缩 文 档。 ZipInputSt

ream 类 完 成 了 所 有 的 工 作 以 使 我 们 能 读 出 压
缩 文 档 中 任 意 一 个 资 源。 我 们 从 包 含 每 个 资 源 的 压 缩 文

 档 中 读 出 准 确 数 目 的 字 节, 并 将 它 们 存 储 在
一 个 可 由 资 源 名 访 问 的 htJarContents 杂 凑 表 中。 

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();

}

}


注 意, 用 来 确 定 每 个 资 源 的 名 字 是 压 缩 文 档 中 资 源 的 实

 际 路 径 名, 而 不 是 包(package) 中 类 的 名 字。 也
就 是 说, java.util.zip 包 中 的ZipEntry 类 的 名 字 应 为“java/util

/zip.ZipEntry ”, 而 不 是"java.util.zip.ZipEntry"。 

这 段 代 码 最 后 一 个 重 要 部 分 是 一 个 简 单 测 试 程 序。 这 个

 测 试 程 序 能 提 取 一 个 压 缩 文 档 名 和 资 源 名。
它 寻 找 压 缩 文 档 中 的 资 源 并 报 告 运 行 成 功 与 否。 

public static void main(String[] args) throws IOException {

if (args.length!=2) {

System.err.println(

"usage: java JarResources "

);

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 中 的 任 何 资 源 上 表 演 你 的
解 压 魔 术。 



--
有求皆苦,无欲则刚

※ 修改:.consultant 于 Feb 18 09:20:18 修改本文.[FROM: 210.78.138.191]
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 210.78.138.191]

[关闭][返回]