获得执行jar的运行路径-使用classloader的getResource方法

在Java处理的文件系统中,目录的表示方式有两种:


(1)绝对目录,它以"/"为起始字符,代表从根目录下开始寻找给出的目录,如/c:/java


(2)相对路径,它以不带“/”的目录名表示,表示以当前Java程序正在运行的目录作为起始目录来寻找给出的目录。如java /classes。在相对路径中,有一些特定的字符,可以代表特的的目录,比如,“.”代表当前目录,“..”代表当前目录的上一级目录。在网上很多给出 的例子中,就是利用"."作为目录名,构造File对象的实例,然后通过File对象的方法来获取当前程序运行的目录。


    这种方法虽然简单,但有时不能正确的得出当前程序的运行目录。原因在于,运行Java程序不一定要进入到该程序的类文件或JAR文件所在的目录,只要在运行时指定了正确的类路径信息,就可以在任何目录中运行Java程序,此时利用这种方法只能得到发出运行命令时所在的目录信息。


     从上面的分析可以看出,对于很多Java程序,尤其是WEB程序,利用当前路径的“.”表示法,都不能满足要求。


利用java.lang.Class的getClassLoader方法,可以获得给定类的ClassLoader实例,它的getResource方法 可以获得当前类装载器中的资源的位置,我们可以利用类文件的名称作为要查找的资源,经过处理后就可获得当前Java程序的运行位置信息,其伪代码如下:
   
    获得Class参数的所在的类名
    取得该类所在的包名
    将包名转换为路径
    利用getResource得到当前的类文件所在URL

    利用URL解析出当前Java程序所在的路径


public static String getAppPath(Class cls) {
        //检查用户传入的参数是否为空
        if (cls == null)
            throw new java.lang.IllegalArgumentException("参数不能为空!");
        ClassLoader loader = cls.getClassLoader();
        //获得类的全名,包括包名
        String clsName = cls.getName() + ".class";
        //获得传入参数所在的包
        Package pack = cls.getPackage();
        String path = "";
        //如果不是匿名包,将包名转化为路径
        if (pack != null) {
            String packName = pack.getName();
            //此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库
            if (packName.startsWith("java.") || packName.startsWith("javax."))
                throw new java.lang.IllegalArgumentException("不要传送系统类!");
            //在类的名称中,去掉包名的部分,获得类的文件名
            clsName = clsName.substring(packName.length() + 1);
            //判定包名是否是简单包名,如果是,则直接将包名转换为路径,
            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) + "/";
            }
        }
       
        //调用ClassLoader的getResource方法,传入包含路径信息的类文件名
        java.net.URL url = loader.getResource(path + clsName);
        //从URL对象中获取路径信息
       
        String realPath = url.getPath();
        //去掉路径信息中的协议名"file:"
        int pos = realPath.indexOf("file:");
        if (pos > -1)
            realPath = realPath.substring(pos + 5);
       
       
        //去掉路径信息最后包含类文件信息的部分,得到类所在的路径
        pos = realPath.indexOf(path + clsName);
        realPath = realPath.substring(0, pos - 1);
       
        //如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名
        if (realPath.endsWith("!"))
            realPath = realPath.substring(0, realPath.lastIndexOf("/"));
       
       
        //结果字符串可能因平台默认编码不同而不同。因此,改用 decode(String,String) 方法指定编码。
        try {
            realPath = java.net.URLDecoder.decode(realPath, "utf-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        System.out.println(realPath);
        return realPath;
    }//getAppPath定义结束


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值