加載 GIF 圖像 假定我們有一個 JAR 文件
其中包含我們的應用程序要使用的一組
gif 圖像
下面就是使用 JarResources 訪問 JAR 文件中的圖像文件的方法
JarResources jar = new JarResources (
Images
jar
);
Image logo =
Toolkit
getDefaultToolkit()
createImage (jar
getResource (
logo
gif
);
這段代碼說明我們可以創建一個 JarResources 對象
並將其初始化為包含我們要使用的資源的 JAR 文件
Images
jar
隨後我們使用 JarResources 的 getResource() 方法將來自 logo
gif 文件的原始數據提供給 AWT Toolkit 的 createImage() 方法
命名說明 JarResource 是一個非常簡單的示例
它說明了如何使用 Java
所提供的各種功能來處理 JAR 和 zip 檔案文件
關於命名的簡要說明
Java 中的歸檔支持實際上是以流行的 zip 歸檔格式為起點的(請參閱
Java Tip
: Use archive files to speed up applet loading
)
因此
在最初實現處理檔案文件的 Java 支持時
所有類文件以及諸如此類的東西並未放在 java
util
zip 包中
這些類通常以
Zip
開頭
但在轉向 Java
時
功能已發生了變化
檔案文件的名稱也更具有 Java 特征
因此
現在我們稱之為 JAR 文件的文件基本上是 zip 文件
工作方式 JarResources 類的重要數據域用來跟蹤和存儲指定 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 {
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 中
您可以通過資源名訪問這些數據
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();
//
表示大小未知
if (size==
) {
size=((Integer)htSizes
get(ze
getName()))
intValue();
}
byte[] b=new byte[(int)size];
int rb=
;
int chunk=
;
while (((int)size
rb) >
) {
chunk=zis
read(b
rb
(int)size
rb);
if (chunk==
) {
break;
}
rb+=chunk;
}
// 添加到內部資源 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
代碼的最後一個重要部分是簡單的測試驅動程序
該測試驅動程序是一個簡單的應用程序
它接收 JAR/zip 檔案名和資源名
它試圖發現檔案中的資源文件
然後將成功或失敗的消息報告出來
public static void main(String[] args) throws IOException {
if (args
length!=
) {
System
err
println(
usage: java JarResources
);
System
exit(
);
}
JarResources jr=new JarResources(args[
]);
byte[] buff=jr
getResource(args[
]);
if (buff==null) {
System
out
println(
Could not find
+args[
]+
);
} else {
System
out
println(
Found
+args[
]+
(length=
+buff
length+
)
);
}
}
} // JarResources 類結束
您已了解了這個類
一個易於使用的類
它隱藏了使用打包在 JAR 文件中的資源的全部棘手問題
練習 現在您對從檔案文件中提取資源已有了一定的認識
下面是可用來修改和擴展 JarResources 類的一些說明
不在構造期間一次性加載全部內容
而要延遲加載
對於大型 JAR 文件
構造期間可能沒有足夠的內存加載全部文件
不只是提供類似 getResource() 這樣的一般讀方法
我們還可提供資源特定的讀方法
例如
用來返回 Java Image 對象的 getImage() 方法
用來返回 Java Class 對象的 getClass() 方法(在自定義的類加載程序的協助下)
等等
如果 JAR 文件足夠小
則我們可以根據它們的擴展名(
gif
class 等等)預先構建全部資源
某些方法應該提供關於給定 JAR 文件本身(基本上是 ZipFile 的包裝)的信息
包括
Jar/zip 的條目數
返回全部資源名的 Enumerator
返回特定條目長度(和其他屬性)的讀方法
允許編制索引的讀方法
這僅僅是舉幾個例子
可對 JarResources 進行擴展
以供 applet 使用
通過利用 applet 參數和 URLConnection 類
就可以從網絡上下載 JAR 內容
而不是將檔案作為本地文件打開
此外
我們還可將該類擴展為一個自定義的 Java 內容處理程序
小結 如果您曾經渴望知道如何從 JAR 文件中提取圖像
那麼您現在已學到了一種方法
有了本技巧提供的這個新類
您就不僅可以用 JAR 文件處理圖像
而且可以將提取魔術用於 JAR 文件中的任何資源
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19350.html