歡迎您光臨本站 註冊首頁

如何利用Java虛擬Unix/Linux的文件路徑

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
   

大部分的java程序應用於UNIX/Linux系統,而絕大部分的開發是在Windows下。雖然,java可以運行在anywhere, 但畢竟還有很多環境配置問題。

 

例如在UNIX下,你需要將某些配置文件的路徑寫入到另一個配置文件。 也許有很多局限,使你必須寫入絕對路徑。

 

在config.properties里寫入

logs = /logs/app/db/logs.properties

configs=/usr/WebSphere/AppServer/installedApps/appname/earname/warname/WEB-INF/properties/myconfig.properties

 

在開發階段,你是否願意在你的Windows開發機上建立上面這樣的目錄,或者逐個修改這個路徑呢? 尤其在已有的系統下,為了開發新的功能,構築開發環境時,這種配置文件路徑的修改是相當花時間的。 並且,在Release時,你必須要使用Ant工具批量修改這些配置文件。 但我可以說,大部分項目只有給生產和系統集成測試環境才會配置Ant工具。而在低級別的測試環境下,你只能手動更改。 那麼如何才能不修改任何文件可以再windows本地調試並運行呢?

 

一下,我給出一個小小方案。

 

1. 重寫java.io.File類

 

先不要向我丟香蕉皮, 重寫java.io.File並不一定要變動rt.jar文件。 jvm支持pretend,也就是偽裝,我可以把我重寫的java.io.File在運行期時代替rt.jar原有的java.io.File類。 想了解更詳細的信息可以在 JAVA_HOME里找這個文件:[ JAVA_HOME]\bin\client\Xusage.txt

 

-Xbootclasspath/p:

prepend in front of bootstrap class path

 

在調試時,我就是要用這個參數。假設,我把重寫的java.io.File類文件打包為filemap_1_4.jar。調試時,我就可以運行 java -Xbootclasspath/p:D:\MyProject\FileMap/filemap_1_4.jar -cp ...

 

這樣,在我調用的所有類里,涉及到文件或文件系統功能時,都調用D:\MyProject\FileMap/filemap_1_4.jar 下面的java.io.File而不是rt.jar.

 

2. 功能實現

 

2.1 文件目錄映射關係

為了增加一些靈活性, 我使用一個目錄映射文件,來定義UNIX/LINUX文件路徑和Windows文件路徑的映射關係。

 

例如,filemap.properties

/usr/WebSphere/AppServer/installedApps/appname/earname/warname/=C:/MyProject/

/logs/app/db/=c:/MyProject/logs

 

當程序要讀取/usr/WebSphere/AppServer/installedApps/appname/earname/warname/WEB-INF/properties/myconfig.properties

 

文件時,java.io.File會映射到C:/MyProject/WEB-INF/properties/myconfig.properties。

 

2.2 java.io.File更改

增加一個靜態變數 private static HashMap filemaps=null;用來保存映射關係。

 

增加一個私有方法 initmaps初始化 filemaps

 

 

/**  * read filemap.propreties to initialize file map.  */  private void initmaps(){  if(filemaps==null){  filemaps=new HashMap();  String filemap=System.getProperty("filemap");   //獲得filemap.properties文件路徑,需要在jvm運行時傳入-Dfilemap=[filemap.properties全路徑名],  不要試圖使用 classloader.getResource(), 因為getResource里也會使用java.io.File,會產生jvm異常。    if(filemap==null || filemap=="")  return;  this.path = fs.normalize(filemap);   //準備讀取filemap.properties文件。因為使用FileInputStream時,  需要傳入一個java.io.File對象,在這暫 時把this.path設為filemap.properties的路徑。    this.prefixLength = fs.prefixLength(this.path);  Properties pro=new Properties();  try {    pro.load(new FileInputStream(this)); //讀取filemap.properties.    Enumeration enumeration=pro.propertyNames();    while(enumeration.hasMoreElements()){  String sourcepath=(String)enumeration.nextElement();   String targetpath=pro.getProperty(sourcepath);  filemaps.put(sourcepath, targetpath); //保存到filemaps靜態對象里。  }  } catch(FileNotFoundException e1){  return;  } catch(IOException e2){  return;  }  }   }

 

 

我們還需要一個私有方法轉換路徑。

 

 

/**  * Get Virutal Path string  * @param name 原UNIX/Linux路徑。  * @return 新windows路徑。  */  private String getVirtualPath(String name){  Iterator sources=filemaps.keySet().iterator();   while(sources.hasNext()){  String source=(String)sources.next();  if(name.startsWith(source)==true){   //當原路徑包含filemaps里某一個source路徑時,將原路徑轉換為新的target路徑。  String target=(String)filemaps.get(source);  name=target+name.substring(source.length());  }  }   return name;  }

 

好了,現在準備在java.io.File里調用這兩個方法。

 

 

/**  * Creates a new File instance by converting the given  * pathname string into an abstract pathname. If the given string is  * the empty string, then the result is the empty abstract pathname.  *  * @param pathname A pathname string  * @throws NullPointerException  * If the pathname argument is null  */  public File(String pathname) {  //new function  initmaps();    if (pathname == null) {  throw new NullPointerException();  }  //new function  pathname=getVirtualPath(pathname);    this.path = fs.normalize(pathname);  this.prefixLength = fs.prefixLength(this.path);  }    public File(String parent, String child) {  //new function  initmaps();    if (child == null) {  throw new NullPointerException();  }  //new function  child=getVirtualPath(child);  parent=getVirtualPath(parent);    if (parent != null) {  if (parent.equals("")) {    this.path = fs.resolve(fs.getDefaultParent(),  fs.normalize(child));  } else {    this.path = fs.resolve(fs.normalize(parent),  fs.normalize(child));  }  } else {  this.path = fs.normalize(child);  }  this.prefixLength = fs.prefixLength(this.path);  }      public File(File parent, String child) {  //new function  initmaps();  child=getVirtualPath(child);    if (child == null) {  throw new NullPointerException();  }  if (parent != null) {  if (parent.path.equals("")) {  this.path = fs.resolve(fs.getDefaultParent(),  fs.normalize(child));  } else {  String parentpath=getVirtualPath(parent.path);   this.path = fs.resolve(parent.path,  fs.normalize(child));  }  } else {  this.path = fs.normalize(child);  }  this.prefixLength = fs.prefixLength(this.path);  }

 

2.3 打包

 

將java.io.File編譯並打包成jar文件。 filemap_1_4.jar

 

2.4 設置調試環境。

 

在你需要調試環境里不需要把這個jar文件發入classpath,但需要在VM arguments里加上

 

-Xbootclasspath/p:C:\MyProject\filemap_1_4.jar -Dfilemap=C:\MyProject\filemap.properties

 

3.測試

編寫測試程序

 

 

import java.io.BufferedReader;  import java.io.File;  import java.io.FileInputStream;  import java.io.FileReader;    public class Test {    /**  * @param args  */  public static void main(String[] args) {  FileReader filereader;  try {  //列印/usr/WebSphere/AppServer/InstallApp/Test.java  filereader = new FileReader(  "/usr/WebSphere/AppServer/InstallApp/Test.java");  BufferedReader bufferedreader = new BufferedReader(filereader);  String line=null;  while((line=bufferedreader.readLine())!=null)  System.out.println(line);  //遍歷/usr/WebSphere/AppServer/InstallApp/Test.java所在的目錄下所有文件,並列印文件名。    File fl=new File("/usr/WebSphere/AppServer/InstallApp/Test.java");  String path=fl.getParent();  String[] files=new File(path).list();  for(int i=0;i System.out.println(files);  }  } catch (Exception e) {  e.printStackTrace();  }  }  }

 

(責任編輯:A6)



[火星人 ] 如何利用Java虛擬Unix/Linux的文件路徑已經有724次圍觀

http://coctec.com/docs/program/show-post-71809.html