qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

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

          處理配置文件對(duì)于Java程序員來(lái)說(shuō)再常見(jiàn)不過(guò)了,不管是Servlet,Spring,抑或是Structs,都需要與配置文件打交道。Java將配置文件當(dāng)作一種資源(resource)來(lái)處理,并且提供了兩個(gè)類(lèi)來(lái)讀取這些資源,一個(gè)是Class類(lèi),另一個(gè)是ClassLoader類(lèi)。

            當(dāng)我們自己的程序需要處理配置文件時(shí)(比如xml文件或properties文件),通常會(huì)遇到兩個(gè)問(wèn)題:

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

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

            在了解了Java加載資源文件的機(jī)制后,以上這兩個(gè)問(wèn)題便迎刃而解了。

            對(duì)于第一個(gè)問(wèn)題,答案是:請(qǐng)將你的資源文件放在classpath里,如果資源文件在jar中,請(qǐng)將該jar文件也加到classpath里面。

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

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

            通過(guò)調(diào)用Class類(lèi)的getResourceAsStream方法來(lái)加載資源文件:

            public InputStream getResourceAsStream(String pathToConfigFile);

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

            舉個(gè)例子,在IntelliJ Idea中創(chuàng)建一個(gè)java工程,目錄結(jié)構(gòu)如下:

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

          name = ConfigUnderDavenkin

            第二個(gè)resources文件夾下也有一個(gè)config.properties文件,其內(nèi)容為:

          name = ConfigUnderSrc

            在davenkin包下定義ResourceLoader.java來(lái)加載資源文件:

          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"));
              }
          }

            輸出結(jié)果為第二個(gè)resources文件夾下config.properties的內(nèi)容:

          ConfigUnderSrc

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

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

            ClassLoader類(lèi)也提供和Class類(lèi)相同的加載方法:

            public InputStream getResourceAsStream(String pathToConfigFile);

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


          在使用Class和ClassLoader加載資源文件時(shí),有幾種區(qū)別細(xì)微的方法,修改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"));
              }
          }

            以上程序輸出結(jié)果為(請(qǐng)仔細(xì)揣摩,稍不小心(比如多加了一個(gè)"/"或少加了一個(gè)"/"),就會(huì)報(bào)NullPointerException異常,表明你的資源文件沒(méi)有找到):

          ConfigUnderSrc
          ConfigUnderSrc
          ConfigUnderDavenkin
          ConfigUnderSrc
          ConfigUnderSrc
          ConfigUnderSrc

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


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2013年4月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 文山县| 民乐县| 济宁市| 利川市| 无棣县| 新和县| 南康市| 沙雅县| 富顺县| 台安县| 南部县| 开鲁县| 永泰县| 开封县| 伽师县| 香格里拉县| 贵阳市| 贵定县| 甘孜县| 罗山县| 丽江市| 贵港市| 江源县| 容城县| 合江县| 五大连池市| 濉溪县| 扬州市| 札达县| 洛阳市| 区。| 大宁县| 墨竹工卡县| 高青县| 奉贤区| 梅州市| 栾城县| 柘荣县| 峨眉山市| 台南县| 德州市|