qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Java加載資源文件的兩種方法

          處理配置文件對于Java程序員來說再常見不過了,不管是Servlet,Spring,抑或是Structs,都需要與配置文件打交道。Java將配置文件當作一種資源(resource)來處理,并且提供了兩個類來讀取這些資源,一個是Class類,另一個是ClassLoader類。

            當我們自己的程序需要處理配置文件時(比如xml文件或properties文件),通常會遇到兩個問題:

            (1)我的配置文件應該放在哪里?

            (2)怎么我的配置文件找不到了?

            在了解了Java加載資源文件的機制后,以上這兩個問題便迎刃而解了。

            對于第一個問題,答案是:請將你的資源文件放在classpath里,如果資源文件在jar中,請將該jar文件也加到classpath里面。

            對于第二個問題,就得看你是使用的是哪個類(Class還是ClassLoader)來加載資源文件了,所以接下來分別討論一下Class類和ClassLoader類對于資源文件的加載機制。

            (一)用Class類加載資源文件

            通過調用Class類的getResourceAsStream方法來加載資源文件:

            public InputStream getResourceAsStream(String pathToConfigFile);

            該方法接收一個String類型的參數(pathToConfigFile)來表示資源文件的地址,如果加載成功,則返回該資源文件的輸入流(InputStream),如果失敗,則返回null。重要的是,在傳入pathToConfigFile參數時,有兩種方式,第一種方式為絕對定位方式,即pathToConfigFile以"/"開頭,此時Java以classpath為根目錄,直接加上pathToConfigFile來搜索資源文件。第二種方式為相對定位方式,即pathToConfigFile不以"/"開頭,此時資源文件的全路徑應該為:調用getResourceAsStream方法的類的package路徑加上pathToConfigFile。(在將package轉為目錄時將"."變成"/")

            舉個例子,在IntelliJ Idea中創建一個java工程,目錄結構如下:

            該工程里有兩個resources文件夾,一個位于davenkin文件夾下,一個直接位于src文件夾下。第一個resources文件夾下有一個config.properties文件,其內容為:

          name = ConfigUnderDavenkin

            第二個resources文件夾下也有一個config.properties文件,其內容為:

          name = ConfigUnderSrc

            在davenkin包下定義ResourceLoader.java來加載資源文件:

          package davenkin;

          import java.io.IOException;
          import java.io.InputStream;
          import java.util.Properties;

          public class ResourceLoader
          {
              public static void main(String[] args) throws IOException
              {
                  ResourceLoader resourceLoader = new ResourceLoader();
                  resourceLoader.loadProperties1();

              }

              public void loadProperties1() throws IOException
              {
                  InputStream input = null;
                  try
                  {
                      input = Class.forName("davenkin.ResourceLoader").getResourceAsStream("/resources/config.properties");

                      //also can be this way:
                      //input = this.getClass().getResourceAsStream("/resources/config.properties");
                  } catch (ClassNotFoundException e)
                  {
                      e.printStackTrace();
                  }
                  printProperties(input);
              }

              private void printProperties(InputStream input) throws IOException
              {
                  Properties properties = new Properties();
                  properties.load(input);
                  System.out.println(properties.getProperty("name"));
              }
          }

            輸出結果為第二個resources文件夾下config.properties的內容:

          ConfigUnderSrc

            原因在于(請注意ReourceLoader.java文件中的紅色部分):我們給出的資源文件路徑(/resources/config.properties)以"/"開頭,即使用的是絕對定位方式,所以找到的是直接在classpath下的resources文件夾。如果去掉資源文件文件路徑前的"/",則采用的是相對定位方式,此時應該輸出davenkin/resources/config.properties文件的內容。

            (二)用ClassLoader類加載資源文件

            ClassLoader類也提供和Class類相同的加載方法:

            public InputStream getResourceAsStream(String pathToConfigFile);

            用ClassLoader加載配置文件時,pathToConfigFile均不能以"/"開頭,在查找時直接在classpath下進行查找。Class類在查找資源文件時,也是代理(delegate)給ClassLoader完成查找功能的,請參考Java官方文檔。


          在使用Class和ClassLoader加載資源文件時,有幾種區別細微的方法,修改ResourceLoader.java文件如下:

          package davenkin;

          import java.io.IOException;
          import java.io.InputStream;
          import java.util.Properties;

          public class ResourceLoader
          {
              public static void main(String[] args) throws IOException
              {
                  ResourceLoader resourceLoader = new ResourceLoader();
                  resourceLoader.loadProperties1();
                  resourceLoader.loadProperties2();
                  resourceLoader.loadProperties3();
                  resourceLoader.loadProperties4();
                  resourceLoader.loadProperties5();
                  resourceLoader.loadProperties6();
              }

              public void loadProperties1() throws IOException
              {
                  InputStream input = null;
                  try
                  {
                      input = Class.forName("davenkin.ResourceLoader").getResourceAsStream("/resources/config.properties");
                  } catch (ClassNotFoundException e)
                  {
                      e.printStackTrace();
                  }
                  printProperties(input);
              }

              public void loadProperties2() throws IOException
              {
                  InputStream input = null;

                  input = this.getClass().getResourceAsStream("/resources/config.properties");
                  printProperties(input);
              }

              public void loadProperties3() throws IOException
              {
                  InputStream input = this.getClass().getResourceAsStream("resources/config.properties");
                  printProperties(input);
              }

              public void loadProperties4() throws IOException
              {
                  InputStream input = this.getClass().getClassLoader().getResourceAsStream("resources/config.properties");
                  printProperties(input);
              }

              public void loadProperties5() throws IOException
              {
                  InputStream input = ClassLoader.getSystemResourceAsStream("resources/config.properties");
                  printProperties(input);
              }

              public void loadProperties6() throws IOException
              {
                  InputStream input = ClassLoader.getSystemClassLoader().getResourceAsStream("resources/config.properties");

                  printProperties(input);
              }

              private void printProperties(InputStream input) throws IOException
              {
                  Properties properties = new Properties();
                  properties.load(input);
                  System.out.println(properties.getProperty("name"));
              }
          }

            以上程序輸出結果為(請仔細揣摩,稍不小心(比如多加了一個"/"或少加了一個"/"),就會報NullPointerException異常,表明你的資源文件沒有找到):

          ConfigUnderSrc
          ConfigUnderSrc
          ConfigUnderDavenkin
          ConfigUnderSrc
          ConfigUnderSrc
          ConfigUnderSrc

          posted on 2013-04-22 09:45 順其自然EVO 閱讀(196) 評論(0)  編輯  收藏


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


          網站導航:
           
          <2013年4月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 武乡县| 武清区| 长顺县| 珲春市| 冷水江市| 双辽市| 安塞县| 东山县| 桂林市| 马龙县| 屯留县| 集贤县| 兴山县| 肥城市| 余干县| 东丰县| 海伦市| 盘山县| 阳城县| 平陆县| 祁连县| 崇信县| 宁陕县| 绥阳县| 都匀市| 盐城市| 汾西县| 正安县| 淄博市| 乌兰浩特市| 阿克陶县| 红安县| 永仁县| 诏安县| 黔西县| 清河县| 灵丘县| 镇江市| 彭泽县| 洛宁县| 仁化县|