Java虚拟Unix/Linux文件路径

大部分的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:<directories and zip/jar files separated by ;>
                      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 <code>File</code> 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 <code>pathname</code> argument is <code>null</code>
     */
    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<files.length;i++){
                System.out.println(files[i]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        

    }

}

 

你可能感兴趣的:(java,windows,String,function,HashMap,null)