多數 java 程序員都非常清楚使用 jar 文件將組成 java 解決方案的各種資源(即 .class 文件、聲音和圖像)打包的優點。剛開始使用 jar 文件的人常問的一個問題是:“如何從 jar 文件中提取圖像呢?”本文將回答這個問題,并會提供一個類,這個類使從 jar 文件中提取任何資源變得非常簡單!
加載 gif 圖像
假定我們有一個 jar 文件,其中包含我們的應用程序要使用的一組 .gif 圖像。下面就是使用 JarResources 訪問 jar 文件中的圖像文件的方法:
JarResources JR=new JarResources(" http://www.bt285.cn /GifBundle.jar");

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

這段代碼說明我們可以創建一個JarResources對象,并將其初始化為包含我們要使用的資源的 jar 文件 -- images.jar。隨后我們使用JarResources的getResource()方法將來自 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;////啊喲!沒有處理子目錄中的資源啊 http://www.5a520.cn 小說520網
}

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 文件中的任何資源。