小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Java程序中的配置文件的存放和讀取

 WindySky 2009-04-02
大家可能經(jīng)常會(huì)遇到在Java程序中存取程序配置文件的需求,比如,為了能夠和不同的數(shù)據(jù)庫(kù)連接,我們經(jīng)常把數(shù)據(jù)庫(kù)連接的信息存放到屬性文件中,這些信息一般包括數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序類名、數(shù)據(jù)庫(kù)連接的URL,數(shù)據(jù)庫(kù)的用戶名和口令等等。為了便于程序的安裝或部署,我們經(jīng)常會(huì)把這些的配置文件存放到程序安裝的根目錄中。由于Java程序用包來(lái)分組類,有時(shí)候?qū)⑦@些配置文件放入到讀取它們的類所在的包目錄中會(huì)更好一些。比如,在下面的圖示中,將數(shù)據(jù)庫(kù)配置文件 database.properties放到數(shù)據(jù)庫(kù)讀取類所在的包目錄就是一種比較清晰的存儲(chǔ)方案:

                        /-----------其它包目錄
                              |
                              |
                              -------edu.ec.database
                                                 |
                                                 |---------------ConnectionPool(數(shù)據(jù)庫(kù)連接池類)
                                                 |
                                                 |---------------Dao(數(shù)據(jù)庫(kù)訪問(wèn)對(duì)象類)
                                                 |
                                                 |---------------DaoFactory(Dao的工廠類)
                                                 |
                                                 |---------------database.properties(數(shù)據(jù)庫(kù)配置屬性文件)
                                                 |
                                                 |---------------RecordSet(記錄集類)
   
在這種存儲(chǔ)方案中,所有的與數(shù)據(jù)庫(kù)相關(guān)的類和配置文件都在同一個(gè)包目錄中;在開(kāi)發(fā)過(guò)程中,配置文件和源文件也按采用這種方式進(jìn)行組織,這樣會(huì)使得程序的數(shù)據(jù)庫(kù)訪問(wèn)維護(hù)變得相當(dāng)清晰明了。

大部分開(kāi)發(fā)工具在編譯打包這樣的源文件組織時(shí),會(huì)自動(dòng)將相關(guān)配置文件和類文件放到生成的目標(biāo)文件夾中或JAR文件中。一般情況下,我們?cè)诎l(fā)布自己的 Java程序時(shí),都是以JAR或WAR形式將程序打包發(fā)布,而對(duì)應(yīng)的配置文件也會(huì)按照上述的目錄格式被放到了JAR或WAR文件中,這樣,就實(shí)現(xiàn)了配置文件和程序文件打包在一起發(fā)布的目的。

現(xiàn)在的問(wèn)題是,我們?nèi)绾巫x取位于程序安裝文件中的配置文件的信息?比如,在上面的圖中, ConnectionPool是一個(gè)數(shù)據(jù)庫(kù)連接池類,它需要在系統(tǒng)啟動(dòng)時(shí)自動(dòng)讀取存儲(chǔ)在database.properties中的數(shù)據(jù)庫(kù)連接和配置信息,以便設(shè)置相關(guān)的數(shù)據(jù)庫(kù)連接。這樣,我們 就需要在程序中測(cè)定目前程序安裝或部署的位置,以便讀取對(duì)應(yīng)的屬性文件。

       在很多其他語(yǔ)言編寫(xiě)的程序中,我們可以利用一些系統(tǒng)提供的API或一些全局對(duì)象獲取目前應(yīng)用程序運(yùn)行所在的目錄。比如VB,我們可以使用Application對(duì)象測(cè)定當(dāng)前程序的安裝位置,在Java程序中如何完成類似的任務(wù)呢?

Java程序并沒(méi)有類似于VB那種全局對(duì)象,但如果我們觀察位于上述目錄結(jié)構(gòu)中的database.properties文件,應(yīng)該發(fā)現(xiàn)其處于應(yīng)用程序的CLASSPATH中,這樣,我們就可以使用Java中的類裝載器中的相關(guān)的方法,讀出這些配置文件的信息,該類名為ClassLoader。比如,在上例中,我們可以先得到ConnectinPool的類裝載器,然后測(cè)定ConnectionPool類所在的包路徑,然后利用 ConnectionPool所在的包目錄讀出database.properties文件的信息,對(duì)應(yīng)的偽代碼如下:

            ClassLoader loader=ConnectionPool.class.getClassLoader();
            得到ConnectionPool所在的包名;
            將包名轉(zhuǎn)換為對(duì)應(yīng)的目錄名,存入一個(gè)名為path的字符串變量中;
           調(diào)用loader的getResourceAsStream(path+"database.properties"),得到輸入流
          
          下面是一個(gè)可實(shí)際運(yùn)行的樣例代碼片段,它可自動(dòng)測(cè)定傳入的類所在的包目錄,返回傳入的屬性文件所代表的輸入流。它還有一個(gè)附加的功能:如果屬性文件直接放到了當(dāng)前類所在的根目錄(比如位于JAR文件的根目錄或WAR文件的WEB-INF/classes目錄中)、系統(tǒng)的用戶目錄系統(tǒng)、系統(tǒng)其他的類路徑中時(shí),它也可以找到;當(dāng)然,如果還是找不到,它將返回null。具體的代碼如下:


        public class PropHelper{
                      /**
                       *guessPropFile:
                       *@param cls:和要尋找的屬性文件處于相同的包中的任意的類
                       *@param propFile:要尋找的屬性文件名
                       */
                   public   static java.io.InputStream guessPropFile(Class cls,String propFile){
                                try{
                                      //得到類的類裝載器
                                      ClassLoader loader=cls.getClassLoader();
                                     
                                      //先從當(dāng)前類所處路徑的根目錄中尋找屬性文件
                                      java.io.InputStream in=loader.getResourceAsStream(propFile);
                                      if(in!=null) return in;
                                     
                                      //沒(méi)有找到,就從該類所處的包目錄中查找屬性文件
                                     Package pack=cls.getPackage();
                                     if(pack!=null){
                                              String packName=pack.getName();
                                              String path="";
                                              if(packName.indexOf(".") < 0 )
                                                 path=packName+"/";
                                              else{
                                                       int start=0,end=0;
                                                       end=packName.indexOf(".");
                                                       while(end!=-1){
                                                             path=path+packName.substring(start,end)+"/";
                                                             start=end+1;
                                                            end=packName.indexOf(".",start);
                                                        }
                                                       path=path+packName.substring(start)+"/";
                                              }
                                              in=loader.getResourceAsStream(path+propFile);
                                              if(in!=null) return in;
                                   }
                                  
                                  //如果沒(méi)有找到,再?gòu)漠?dāng)前系統(tǒng)的用戶目錄中進(jìn)行查找
                                  java.io.File f=null;
                                  String curDir=System.getProperty("user.dir");
                                  f=new java.io.File(curDir,propFile);
                                  if(f.exists()) return new java.io.FileInputStream(f);
                                 
                                  //如果還是沒(méi)有找到,則從系統(tǒng)所有的類路徑中查找
                                  String classpath=System.getProperty("java.class.path");
                                  String[] cps=classpath.split(System.getProperty("path.separator"));
                                 
                                  for(int i=0;i < cps.length; i++){
                                           f=new java.io.File(cps[i],propFile);
                                           if(f.exists()) break;
                                           f=null;
                                   }
                                  if(f!=null) return new java.io.FileInputStream(f);
                                  return null;
                            }catch(Exception e){throw new RuntimeException(e);}
                  
                     }
        }
        
使用舉例:利用上述的方法,可在ConnectionPool中自動(dòng)查找和ConnectionPool處于同一個(gè)包目錄中的database.properties的輸入流,并利用該輸入流讀入對(duì)應(yīng)的屬性值的代碼如下:
       public class ConnectionPool{
            //靜態(tài)初始化器,將在ConnectionPools加載時(shí)自動(dòng)執(zhí)行
           static{
               java.util.Properties dbProp=new java.util.Properties();
               java.io.InputStream in=PropHelper.guessPropFile(edu.ec.database.ConnectionPool.class,"database.properties");
               if(in!=null) dbProp.load(in);
               //利用dbProp,為相應(yīng)的數(shù)據(jù)源對(duì)象設(shè)置相關(guān)的屬性,比如C3P0........
            }
     }
--------------------------------------------------------------------------------------------------------
程序打包成Jar發(fā)布后,應(yīng)該將配置文件放在jar的當(dāng)前同級(jí)目錄,訪問(wèn)調(diào)用直接訪問(wèn),如
java.util.Properties pro = new java.util.Properties();
InputStream inStream = new java.io.FileInputStream("database.properties");pro.load(inStream);
如果是打包成WAR發(fā)布,則放在適合LZ的方法
----------------------------------------------------------
永久域名 http://hdwangyi.
2007-07-26

Java程序中的配置文件的存放和讀取

關(guān)鍵字: 數(shù)據(jù)庫(kù) 屬性文件 類路徑
大家可能經(jīng)常會(huì)遇到在Java程序中存取程序配置文件的需求,比如,為了能夠和不同的數(shù)據(jù)庫(kù)連接,我們經(jīng)常把數(shù)據(jù)庫(kù)連接的信息存放到屬性文件中,這些信息一般包括數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序類名、數(shù)據(jù)庫(kù)連接的URL,數(shù)據(jù)庫(kù)的用戶名和口令等等。為了便于程序的安裝或部署,我們經(jīng)常會(huì)把這些的配置文件存放到程序安裝的根目錄中。由于Java程序用包來(lái)分組類,有時(shí)候?qū)⑦@些配置文件放入到讀取它們的類所在的包目錄中會(huì)更好一些。比如,在下面的圖示中,將數(shù)據(jù)庫(kù)配置文件 database.properties放到數(shù)據(jù)庫(kù)讀取類所在的包目錄就是一種比較清晰的存儲(chǔ)方案:

                        /-----------其它包目錄
                              |
                              |
                              -------edu.ec.database
                                                 |
                                                 |---------------ConnectionPool(數(shù)據(jù)庫(kù)連接池類)
                                                 |
                                                 |---------------Dao(數(shù)據(jù)庫(kù)訪問(wèn)對(duì)象類)
                                                 |
                                                 |---------------DaoFactory(Dao的工廠類)
                                                 |
                                                 |---------------database.properties(數(shù)據(jù)庫(kù)配置屬性文件)
                                                 |
                                                 |---------------RecordSet(記錄集類)
   
在這種存儲(chǔ)方案中,所有的與數(shù)據(jù)庫(kù)相關(guān)的類和配置文件都在同一個(gè)包目錄中;在開(kāi)發(fā)過(guò)程中,配置文件和源文件也按采用這種方式進(jìn)行組織,這樣會(huì)使得程序的數(shù)據(jù)庫(kù)訪問(wèn)維護(hù)變得相當(dāng)清晰明了。

大部分開(kāi)發(fā)工具在編譯打包這樣的源文件組織時(shí),會(huì)自動(dòng)將相關(guān)配置文件和類文件放到生成的目標(biāo)文件夾中或JAR文件中。一般情況下,我們?cè)诎l(fā)布自己的 Java程序時(shí),都是以JAR或WAR形式將程序打包發(fā)布,而對(duì)應(yīng)的配置文件也會(huì)按照上述的目錄格式被放到了JAR或WAR文件中,這樣,就實(shí)現(xiàn)了配置文件和程序文件打包在一起發(fā)布的目的。

現(xiàn)在的問(wèn)題是,我們?nèi)绾巫x取位于程序安裝文件中的配置文件的信息?比如,在上面的圖中, ConnectionPool是一個(gè)數(shù)據(jù)庫(kù)連接池類,它需要在系統(tǒng)啟動(dòng)時(shí)自動(dòng)讀取存儲(chǔ)在database.properties中的數(shù)據(jù)庫(kù)連接和配置信息,以便設(shè)置相關(guān)的數(shù)據(jù)庫(kù)連接。這樣,我們 就需要在程序中測(cè)定目前程序安裝或部署的位置,以便讀取對(duì)應(yīng)的屬性文件。

       在很多其他語(yǔ)言編寫(xiě)的程序中,我們可以利用一些系統(tǒng)提供的API或一些全局對(duì)象獲取目前應(yīng)用程序運(yùn)行所在的目錄。比如VB,我們可以使用Application對(duì)象測(cè)定當(dāng)前程序的安裝位置,在Java程序中如何完成類似的任務(wù)呢?

Java程序并沒(méi)有類似于VB那種全局對(duì)象,但如果我們觀察位于上述目錄結(jié)構(gòu)中的database.properties文件,應(yīng)該發(fā)現(xiàn)其處于應(yīng)用程序的CLASSPATH中,這樣,我們就可以使用Java中的類裝載器中的相關(guān)的方法,讀出這些配置文件的信息,該類名為ClassLoader。比如,在上例中,我們可以先得到ConnectinPool的類裝載器,然后測(cè)定ConnectionPool類所在的包路徑,然后利用 ConnectionPool所在的包目錄讀出database.properties文件的信息,對(duì)應(yīng)的偽代碼如下:

            ClassLoader loader=ConnectionPool.class.getClassLoader();
            得到ConnectionPool所在的包名;
            將包名轉(zhuǎn)換為對(duì)應(yīng)的目錄名,存入一個(gè)名為path的字符串變量中;
           調(diào)用loader的getResourceAsStream(path+"database.properties"),得到輸入流
          
          下面是一個(gè)可實(shí)際運(yùn)行的樣例代碼片段,它可自動(dòng)測(cè)定傳入的類所在的包目錄,返回傳入的屬性文件所代表的輸入流。它還有一個(gè)附加的功能:如果屬性文件直接放到了當(dāng)前類所在的根目錄(比如位于JAR文件的根目錄或WAR文件的WEB-INF/classes目錄中)、系統(tǒng)的用戶目錄系統(tǒng)、系統(tǒng)其他的類路徑中時(shí),它也可以找到;當(dāng)然,如果還是找不到,它將返回null。具體的代碼如下:


        public class PropHelper{
                      /**
                       *guessPropFile:
                       *@param cls:和要尋找的屬性文件處于相同的包中的任意的類
                       *@param propFile:要尋找的屬性文件名
                       */
                   public   static java.io.InputStream guessPropFile(Class cls,String propFile){
                                try{
                                      //得到類的類裝載器
                                      ClassLoader loader=cls.getClassLoader();
                                     
                                      //先從當(dāng)前類所處路徑的根目錄中尋找屬性文件
                                      java.io.InputStream in=loader.getResourceAsStream(propFile);
                                      if(in!=null) return in;
                                     
                                      //沒(méi)有找到,就從該類所處的包目錄中查找屬性文件
                                     Package pack=cls.getPackage();
                                     if(pack!=null){
                                              String packName=pack.getName();
                                              String path="";
                                              if(packName.indexOf(".") < 0 )
                                                 path=packName+"/";
                                              else{
                                                       int start=0,end=0;
                                                       end=packName.indexOf(".");
                                                       while(end!=-1){
                                                             path=path+packName.substring(start,end)+"/";
                                                             start=end+1;
                                                            end=packName.indexOf(".",start);
                                                        }
                                                       path=path+packName.substring(start)+"/";
                                              }
                                              in=loader.getResourceAsStream(path+propFile);
                                              if(in!=null) return in;
                                   }
                                  
                                  //如果沒(méi)有找到,再?gòu)漠?dāng)前系統(tǒng)的用戶目錄中進(jìn)行查找
                                  java.io.File f=null;
                                  String curDir=System.getProperty("user.dir");
                                  f=new java.io.File(curDir,propFile);
                                  if(f.exists()) return new java.io.FileInputStream(f);
                                 
                                  //如果還是沒(méi)有找到,則從系統(tǒng)所有的類路徑中查找
                                  String classpath=System.getProperty("java.class.path");
                                  String[] cps=classpath.split(System.getProperty("path.separator"));
                                 
                                  for(int i=0;i < cps.length; i++){
                                           f=new java.io.File(cps[i],propFile);
                                           if(f.exists()) break;
                                           f=null;
                                   }
                                  if(f!=null) return new java.io.FileInputStream(f);
                                  return null;
                            }catch(Exception e){throw new RuntimeException(e);}
                  
                     }
        }
        
使用舉例:利用上述的方法,可在ConnectionPool中自動(dòng)查找和ConnectionPool處于同一個(gè)包目錄中的database.properties的輸入流,并利用該輸入流讀入對(duì)應(yīng)的屬性值的代碼如下:
       public class ConnectionPool{
            //靜態(tài)初始化器,將在ConnectionPools加載時(shí)自動(dòng)執(zhí)行
           static{
               java.util.Properties dbProp=new java.util.Properties();
               java.io.InputStream in=PropHelper.guessPropFile(edu.ec.database.ConnectionPool.class,"database.properties");
               if(in!=null) dbProp.load(in);
               //利用dbProp,為相應(yīng)的數(shù)據(jù)源對(duì)象設(shè)置相關(guān)的屬性,比如C3P0........
            }
     }
評(píng)論
tvjody 2007-08-20   回復(fù)
deadcode 寫(xiě)道
這個(gè)道路是不是有些曲折?
要是程序被打包了,要改個(gè)配置還要重新打包?

配置文件多的話還是集中起來(lái)管理比較直觀,而且很多可以在系統(tǒng)啟動(dòng)時(shí)先加載,一般也就一次.
程序打包成Jar發(fā)布后,應(yīng)該將配置文件放在jar的當(dāng)前同級(jí)目錄,訪問(wèn)調(diào)用直接訪問(wèn),如
java.util.Properties pro = new java.util.Properties();
InputStream inStream = new java.io.FileInputStream("database.properties");pro.load(inStream);
如果是打包成WAR發(fā)布,則放在適合LZ的方法
deadcode 2007-08-14   回復(fù)
這個(gè)道路是不是有些曲折?
要是程序被打包了,要改個(gè)配置還要重新打包?

配置文件多的話還是集中起來(lái)管理比較直觀,而且很多可以在系統(tǒng)啟動(dòng)時(shí)先加載,一般也就一次.
hdwangyi 2007-07-26   回復(fù)
    現(xiàn)在,guessPropFile可以自動(dòng)在如下位置中尋找屬性文件:
   

       
  1. 在未打包的Java程序的類文件所在的根目錄中尋找屬性文件
  2.    
  3. 在打包的JAR程序的根目錄中尋找屬性文件
  4.    
  5. 在未打包的Java類文件所在的根目錄中對(duì)應(yīng)傳入?yún)?shù)類所在的包目錄中尋找屬性文件
  6.    
  7. 在打包的JAR文件中對(duì)應(yīng)傳入?yún)?shù)類所在的包目錄中尋找屬性文件
  8.    
  9. 在未打包及打包的WAR文件夾中的WEB-INF/classes目錄中尋找屬性文件
  10.    
  11. 在未打包及打包的WAR文件中的WEB-INF/classes目錄中對(duì)應(yīng)傳入?yún)?shù)類所在的包目錄中尋找屬性文件
  12.    
  13. 在操作系統(tǒng)中的當(dāng)前登錄用戶的主目錄中尋找屬性文件
  14.    
  15. 在系統(tǒng)設(shè)定的環(huán)境變量CLASSPATH所指向的各個(gè)目錄中尋找屬性文件
  16.    

 
    其實(shí),guessPropFile方法還可做的更加智能一些,比如在WAR文件的WEB-INF文件中尋找屬性文件。如果要完成這個(gè)任務(wù),ClassLoader是關(guān)鍵類,利用它的getResource方法,就可以獲得相應(yīng)程序中的資源的位置,我們可以在它的基礎(chǔ)上稍加修改就可獲得當(dāng)前Java程序的運(yùn)行位置信息,其偽代碼如下:
  獲得Class參數(shù)的所在的類名
  取得該類所在的包名
  將包名轉(zhuǎn)換為路徑
  利用getResource得到當(dāng)前的類文件所在URL
  利用URL解析出當(dāng)前Java程序所在的路徑
具體代碼如下:
Java代碼 復(fù)制代碼
  1. public class PropHelper{   
  2.  //其他方法的定義   
  3.  //.............   
  4.   
  5.  /**  
  6.   *getAppPath需要一個(gè)當(dāng)前程序使用的Java類的class屬性參數(shù),它可以返回打包過(guò)的  
  7.   *Java可執(zhí)行文件(jar,war)所處的系統(tǒng)目錄名或非打包Java程序所處的目錄  
  8.   *@param cls為Class類型  
  9.   *@return 返回值為該類所在的Java程序運(yùn)行的目錄  
  10.   */  
  11.  public static String getAppPath(Class cls){   
  12.      ClassLoader loader=cls.getClassLoader();   
  13.      String clsName=cls.getName()+".class";   
  14.      Package pack=cls.getPackage();   
  15.      String path="";   
  16.      if(pack!=null){   
  17.          String packName=pack.getName();   
  18.          clsName=clsName.substring(packName.length()+1);   
  19.          if(packName.indexOf(".")<0) path=packName+"/";   
  20.          else{   
  21.              int start=0,end=0;   
  22.              end=packName.indexOf(".");   
  23.              while(end!=-1){   
  24.                  path=path+packName.substring(start,end)+"/";   
  25.                  start=end+1;   
  26.                  end=packName.indexOf(".",start);   
  27.              }   
  28.              path=path+packName.substring(start)+"/";   
  29.          }   
  30.      }   
  31.      java.net.URL url =loader.getResource(path+clsName);   
  32.      String realPath=url.getPath();   
  33.      int pos=realPath.indexOf("file:");   
  34.      if(pos>-1) realPath=realPath.substring(pos+5);   
  35.      pos=realPath.indexOf(path+clsName);   
  36.      realPath=realPath.substring(0,pos-1);   
  37.      if(realPath.endsWith("!"))   
  38.          realPath=realPath.substring(0,realPath.lastIndexOf("/"));   
  39.      return realPath;   
  40.  }//getAppPath定義結(jié)束   
  41.   
  42. /PropHelper類定義結(jié)束  

在getAppPath方法的幫助下,我們可以測(cè)定當(dāng)前程序運(yùn)行的路徑是不是包含WEB-INF/classes路徑信息,如果是,則當(dāng)前程序就可能是運(yùn)行在Web環(huán)境中,這樣,就可以對(duì)guessPropFile中的代碼進(jìn)行增加,加入在WEB-INF文件夾尋找屬性文件的方法。
 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多