eroself

          關于人生的程式,在這里譜寫......
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理

          轉自:http://blog.csdn.net/ruyanhai/archive/2007/11/07/1871663.aspx

          一般情況下,我們都使用相對路徑來獲取資源,這樣的靈活性比較大.

          比如當前類為com/bbebfe/Test.class

          而圖像資源比如sample.gif應該放置在com/bbebfe/sample.gif

          而如果這些圖像資源放置在icons目錄下,則應該是com/bbebfe/icons/sample.gif

          通過當前類文件的路徑獲取資源主要有如下幾種方式:

          · 假設當前類為com.bbebfe.Test

          · 包所在的文件夾為bin

          String imageName = "icons/sample.gif"

          1, 通過Class.getResource()定位類路徑下的資源(bin/com/bbebfe/icons/sample.gif)

          Class clazz = this.getClass();

          URL url = clazz.getResource(imageName);

          2,通過ClassLoader.getResource()定位包的根目錄下的資源(bin/icons/sample.gif)

          Class clazz = this.getClass();

          URLClassLoader loader = (URLClassLoader)clazz.getClassLoader();

          URL url = loader.getResource(imageName);

          3, 通過ClassLoader.findResource()提供自己定制的方式定位資源

          URL url = loader.findResource(imageName);

           

          那么這三種方法有那些區別, 我們應該在何時使用哪種方法呢?

          · Class.getResource() 方法

          該方法實際通過該ClassClass LoadergetResource()方法來獲得資源, 在調用ClassLoadergetResource()方法之前, Class.getResource()方法會對資源名稱做一定的處理,構建一個該資源的絕對名稱(absolute name, 大意是:

                 如果資源名稱以'/'('"u002f') 開始, 則資源的絕對名稱是'/'以后的部分.

                        如果imageName"/icons/sample.gif", 則在這里會變成"icons/sample.gif"

                 否則對于其他情況, 絕對名稱將是如下形式(給資源名稱的前面加上modified_package_name/):
                        modified_package_name/resource_name (修正的包名稱/資源名稱)

          其中修正的包名稱含義是將當前對象所在的包名稱中的'.'('"u002e')替換為'/'

          如果ClassLoader.getResource()方法返回一個值為nullURL, Class.getResource()方法最終會將資源請求交給ClassLoader.getSystemResource(java.lang.String).

          · ClassLoader.getResource() 方法

          該對資源進行查找, 資源的名稱是以'/'分隔的路徑, 這個方法首先查找自己的父親ClassLoader, 由自己的父ClassLoader來查找資源(實際上, 如果父親的父親不是空, 則父親仍會向上提交查找請求). 如果自己的父ClassLoadernull, 則查找Java虛擬機中內建的class loader, 并將資源請求提交給它們, 如果這些操作都失敗了, ClassLoader會調用自己的findResource()方法來查找資源.

          · ClassLoader.findResource() 方法

          該方法在內部查找指定的資源, 如果你實現了自己的Class Loader,則應該重載這個方法以自己特定的方式來查找類文件和資源.

           

          通過以上的總結, 我們可以看到三點.

          1, 無論是getResource(), 還是findResource(), 這些方法都只是資源的定位方法, 最終都只是返回一個URL, 只是對資源的定位而已, 我們隨后應通過自己的方法來讀取這些資源. 而在ClassClassLoader中還定義的有getResourceAsStream方法, 該方法是getResource的增強版, 這里就不介紹了.

          2,如果需要以類為相對路徑查找資源, 則應該調用Class.getResource()方法, 不要直接調用ClassLoader.getResource()方法. 另外, 除非是你自己定義了ClassLoader并重載了findResource方法,否則也不要直接調用ClassLoader.findResource方法, 因為在Class.getResource()方法中會對資源名稱作一定的處理, 這在上面介紹了, 下面舉個實例:

                 假設我的當前類在Eclipse工程Database, 類所在的包是com.bbebfe.test, icons目錄放在bin/com/bbebfe/test/目錄下, 我需要得到icons/sample.gif文件的URL, 則調用this.getClass().getResource()得到的URL:

                 file:/E:/MyLife/MyProjects/Eclipse3.2/Database/bin/com/bbebfe/test/icons/disremove.gif

           

          3, 有時候我們希望某個jar庫的圖像資源在同一個icons下統一管理, 而不是為每個包下面的Class建一個icons, 也就是說需要以庫為相對路徑來查找資源, 此時則應該調用ClassLoader.getResource()方法, 舉個例子:

          ·某個工程有如下的包結構:

                 com.bbebfe.ui

                 com.bbebfe.test

                 com.bbebfe.database

          ·如果以類為相對路徑, 則在每個包下都必須建立一個icons目錄, 并放置相應的資源文件. 如下:

                 com.bbebfe.ui/icons/...

                 com.bbebfe.test/icons/...

                 com.bbebfe.database/icons/...

          ·而我們可能希望在根目錄下放置一個icons目錄, 把所有資源放置在這里管理, 這樣還可以防止資源的重復. 就是如下形式

                 com.bbebfe.ui

                 com.bbebfe.test

                 com.bbebfe.database

                 icons/sample.gif ...

                 則此時我們應該調用ClassLoader.getResource方法, 由于它沒有對資源名稱作處理, 也就是說沒有將修正的包名添加到資源名稱前, 所以它會在類所在的包的根下去查找資源.(運行java程序的語法是java com.bbebfe.ui.Test, 所以根目錄com目錄的上級目錄).

           

          最后, Java中對資源進行定位的方法有很多種, Eclipse源代碼中還有如下一段定位文件資源的代碼, 還沒有時間研究, 以后再談:

          ProtectionDomain domain = Main.class.getProtectionDomain();

          CodeSource source = null;

          URL result = null;

          if (domain != null)

          source = domain.getCodeSource();//獲得code source

          if (source != null)

                result = source.getLocation();//獲得URL

                    

          String path = decode(result.getFile());//

          // normalize to not have leading / so we can check the form

          File file = new File(path);

          path = file.toString().replace('""', '/');

          // create a file URL (via File) to normalize the form (e.g., put

          // the leading / on if necessary)

          path = new File(path).toURL().getFile();


          評論

          # re: Java中如何以類為相對路徑或以庫為相對路徑定位資源 [未登錄]  回復  更多評論   

          2010-01-28 11:26 by aa

          ?

          # re: Java中如何以類為相對路徑或以庫為相對路徑定位資源 [未登錄]  回復  更多評論   

          2010-01-28 11:26 by 倫理電影

          還是米獲取到絕對路徑 ,老是相對路徑!
          主站蜘蛛池模板: 伊宁县| 托克逊县| 永修县| 天津市| 湘乡市| 阿拉善右旗| 衡东县| 乌恰县| 万载县| 木里| 许昌市| 文山县| 尉犁县| 汕头市| 永靖县| 涞水县| 科技| 巴青县| 贵州省| 临澧县| 蓬溪县| 峡江县| 土默特左旗| 龙井市| 西乌珠穆沁旗| 南开区| 阆中市| 赤峰市| 岑溪市| 峨山| 礼泉县| 响水县| 浦县| 沙雅县| 海阳市| 安龙县| 施甸县| 扎兰屯市| 怀远县| 卫辉市| 罗山县|