荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: icefire (......), 信区: Java
标 题: 如 何 从JAR 和ZIP 包 中 析 取Java 源 文 件
发信站: BBS 荔园晨风站 (Mon Feb 1 09:38:29 1999), 站内信件 (WWW POST)
如 何 从JAR 和ZIP 包 中 析 取Java 源 文 件
--------------------------------------------------------------------------------
---- 摘 要:
---- 将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 类 访 问 压 缩 文 档。ZipInputStream
类 完 成 了 所 有 的 工 作 以 使 我 们 能 读 出 压 缩 文 档 中 任 意 一 个 资 源
。 我 们 从 包 含 每 个 资 源 的 压 缩 文 档 中 读 出 准 确 数 目 的 字 节, 并
将 它 们 存 储 在 一 个 可 由 资 源 名 访 问 的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 中 的 任 何
资 源 上 表 演 你 的 解 压 魔 术。
--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.0.30]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店