Open-Source World

          let's learn and study.
          posts - 28, comments - 23, trackbacks - 0, articles - 1
          多數(shù) java 程序員都非常清楚使用 jar 文件將組成 java 解決方案的各種資源(即 .class 文件、聲音和圖像)打包的優(yōu)點(diǎn)。剛開始使用 jar 文件的人常問的一個(gè)問題是:“如何從 jar 文件中提取圖像呢?”本文將回答這個(gè)問題,并會(huì)提供一個(gè)類,這個(gè)類使從 jar 文件中提取任何資源變得非常簡單!

            加載 gif 圖像

            假定我們有一個(gè) jar 文件,其中包含我們的應(yīng)用程序要使用的一組 .gif 圖像。下面就是使用 JarResources 訪問 jar 文件中的圖像文件的方法:

          JarResources JR=new JarResources("GifBundle.jar");

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

            這段代碼說明我們可以創(chuàng)建一個(gè)JarResources對象,并將其初始化為包含我們要使用的資源的 jar 文件 -- images.jar。隨后我們使用JarResources的getResource()方法將來自 logo.gif 文件的原始數(shù)據(jù)提供給 awt Toolkit 的createImage()方法。

            命名說明

            JarResource 是一個(gè)非常簡單的示例,它說明了如何使用 java 所提供的各種功能來處理 jar 和 zip 檔案文件。

            工作方式

            JarReources類的重要數(shù)據(jù)域用來跟蹤和存儲(chǔ)指定 jar 文件的內(nèi)容:

          public final class JarResources {
          public boolean debugon=false;
          private Hashtable htsizes=new Hashtable();
          private Hashtable htjarcontents=new Hashtable();
          private String jarfilename;

            這樣,該類的實(shí)例化設(shè)置 jar 文件的名稱,然后轉(zhuǎn)到init()方法完成全部實(shí)際工作。

          public JarResources(String jarfilename) {
          this.jarfilename=jarfilename;
          init();
          }

            現(xiàn)在,init()方法只將指定 jar 文件的整個(gè)內(nèi)容加載到一個(gè) hashtable(通過資源名訪問)中。

            這是一個(gè)相當(dāng)有用的方法,下面我們對它作進(jìn)一步的分析。ZipFile類為我們提供了對 jar/zip 檔案頭信息的基本訪問方法。這類似于文件系統(tǒng)中的目錄信息。下面我們列出ZipFile中的所有條目,并用檔案中每個(gè)資源的大小添充 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類完成了全部魔術(shù),允許我們單獨(dú)讀取檔案中的每個(gè)資源。我們從檔案中讀取組成每個(gè)資源的精確字節(jié)數(shù),并將其存儲(chǔ)在 htjarcontents hashtable 中,您可以通過資源名訪問這些數(shù)據(jù):

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

            請注意,用來標(biāo)識每個(gè)資源的名稱是檔案中資源的限定路徑名,例如,不是包中的類名 -- 即 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);
          }

            代碼的最后一個(gè)重要部分是簡單的測試驅(qū)動(dòng)程序。該測試驅(qū)動(dòng)程序是一個(gè)簡單的應(yīng)用程序,它接收 jar/zip 檔案名和資源名。它試圖發(fā)現(xiàn)檔案中的資源文件,然后將成功或失敗的消息報(bào)告出來:

          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.

            您已了解了這個(gè)類。一個(gè)易于使用的類,它隱藏了使用打包在 jar 文件中的資源的全部棘手問題。

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 郑州市| 安图县| 乌审旗| 毕节市| 台东县| 无锡市| 巴东县| 乐清市| 松溪县| 邵武市| 淅川县| 垣曲县| 汾西县| 合水县| 皮山县| 漳州市| 永年县| 蓬溪县| 南京市| 香格里拉县| 金溪县| 保德县| 绥化市| 嫩江县| 泰安市| 南木林县| 礼泉县| 韩城市| 奇台县| 高淳县| 扎鲁特旗| 西华县| 仙居县| 洛阳市| 苏州市| 盐城市| 吉木萨尔县| 三明市| 治多县| 嘉兴市| 会宁县|