• Java在J2EE工程中路径寻址问题终极解决方案


    前言

    Java的路径问题,非常难搞。最近的工作涉及到创建和读取文件的工作,这里我就给大家彻底得解决Java路径问题。

     

    Java路径

    Java中使用的路径,分为两种:绝对路径和相对路径。具体而言,又分为四种:

     

    一、 URI形式的绝对资源路径

     

    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

     

    URLURI的特例。URL的前缀/协议,必须是Java认识的。URL可以打开资源,而URI则不行。

     

    URLURI对象可以互相转换,使用各自的toURI(),toURL()方法即可!

     

    二、 本地系统的绝对路径

     

    D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

     

    Java.io包中的类,需要使用这种形式的参数。

     

    但是,它们一般也提供了URI类型的参数,而URI类型的参数,接受的是URI样式的String。因此,通过URI转换,还是可以把URI样式的绝对路径用在java.io包中的类中。

     

    三、 相对于classpath的相对路径

     

     如:相对于

     

    file:/D:/java/eclipse32/workspace/jbpmtest3/bin/这个路径的相对路径。其中,bin是本项目的classpath。所有的Java源文件编译后的.class文件复制到这个目录中。

     

    四、 相对于当前用户目录的相对路径

     

    就是相对于System.getProperty("user.dir")返回的路径。

     

    对于一般项目,这是项目的根路径。

     

    对于JavaEE服务器,这可能是服务器的某个路径。这个并没有统一的规范!

     

    所以,绝对不要使用相对于当前用户目录的相对路径。然而:

    默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。

     

    这就是说,在使用java.io包中的类时,最好不要使用相对路径。否则,虽然在J2SE应用程序中可能还算正常,但是到了J2EE程序中,一定会出问题!而且这个路径,在不同的服务器中都是不同的!

     

     

    相对路径最佳实践

    推荐使用相对于当前classpath的相对路径,因此,我们在使用相对路径时,应当使用相对于当前classpath的相对路径

    1) ClassLoader类的getResource(String name) getResourceAsStream(String name)等方法,使用相对于当前项目的classpath的相对路径来查找资源。

     

    2) 读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此

    通过查看ClassLoader类及其相关类的源代码,我发现,它实际上还是使用了URI形式的绝对路径。

     

    相对路径本质上还是绝对路径

    因此,归根结底java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是API在底层帮助我们构建了绝对路径,从而找到资源。

    下面是一些得到classpath和当前类的绝对路径的一些方法,你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。

    1FileTest.class.getResource("")

    得到的是当前类FileTest.class文件的URI目录。不包括自己!

    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/

    2FileTest.class.getResource("/")

    得到的是当前的classpath的绝对URI路径。

    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

    3Thread.currentThread().getContextClassLoader().getResource("")

    得到的也是当前ClassPath的绝对URI路径。

    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

    4FileTest.class.getClassLoader().getResource("")

    得到的也是当前ClassPath的绝对URI路径。

    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

    5ClassLoader.getSystemResource("")

    得到的也是当前ClassPath的绝对URI路径。

    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

     

    我推荐使用Thread.currentThread().getContextClassLoader().getResource("")来得到当前的classpath的绝对路径的URI表示法。

     

     

    public class PathUtil {

    /***********************************************这些都是J2EE环境下的路径,不适合J2SE环境**************************************************************
    * 1)obj.getClass().getClassLoader().getResource()>>>>>>>>>file:/E:/workspace/STY/Web/STY/WEB-INF/classes/(取到的classPath的路径)
    * 2)obj.getClass().getClassLoader().getResource("/")>>>>>>>>null(是取不到路径的)
    *
    * 3)obj.getClass().getResource("")>>>>>>>>>file:/E:/workspace/STY/Web/STY/WEB-INF/classes/com/path/(取的是当前文件的文件夹路径,不包括该文件名)
    * 4)obj.getClass().getResource("/")>>>>>>>>>file:/E:/workspace/STY/Web/STY/WEB-INF/classes/(取到的classPath的路径)
    *
    * 5)obj.getClass().getResource("1.xml")>>>>>>>>>file:/E:/workspace/STY/Web/STY/WEB-INF/classes/com/path/1.xml(可以使用相对路径)
    * 6)obj.getClass().getClassLoader().getResource(com/path/1.xml"/")>>>>>>>>file:/E:/workspace/STY/Web/STY/WEB-INF/classes/com/path/1.xml(使用相对路径)
    *
    * 7)obj.getClass().getResource("/com/path/1.xml")>>>>>>>>file:/E:/workspace/STY/Web/STY/WEB-INF/classes/com/path/1.xml(使用相对路径)
    *
    * 总结:
    * obj.getClass().getClassLoader().getResource()可以直接得到classpath,然后通过classpath进行相对地址取地址
    * obj.getClass().getResource("/")也可以直接得到classpath,然后通过相对地址取地址
    * obj.getClass().getResource("") 可以得到该类所存放的文件夹目录,然后通过相对地址取地址
    ***********************************************************************************************************************************************/
    public static void main(String[] args) {

     

    PathUtil obj = new PathUtil();

    //1、obj.getClass().getClassLoader().getResource("")
    String TestString = "obj.getClass().getClassLoader().getResource(" + ")";
    System.out.println(TestString + ">>>>>>>>>" + obj.getClass().getClassLoader().getResource("com/../com/path/1.xml").getPath());

     

    //2、obj.getClass().getClassLoader().getResource("/")
    TestString = "obj.getClass().getClassLoader().getResource(" + ""/"" + ")";
    System.out.println(TestString + ">>>>>>>>" + obj.getClass().getClassLoader().getResource("/"));


    //3、obj.getClass().getResource("").getPath()
    TestString = "obj.getClass().getResource("+""")";
    System.out.println(TestString + ">>>>>>>>>" + obj.getClass().getResource("").getPath());

    //4、obj.getClass().getResource("/")
    TestString ="obj.getClass().getResource(" + ""/"" +")";
    System.out.println(TestString + ">>>>>>>>>" + obj.getClass().getResource("/").getPath());

    //5、obj.getClass().getResource("1.xml")
    TestString = "obj.getClass().getResource("+""1.xml")";
    System.out.println(TestString + ">>>>>>>>>" + obj.getClass().getResource("1.xml").getPath());

    //6、obj.getClass().getClassLoader().getResource("com/path/1.xml")
    TestString = "obj.getClass().getClassLoader().getResource(" + "com/path/1.xml"/"" + ")";
    System.out.println(TestString + ">>>>>>>>" + obj.getClass().getClassLoader().getResource("com/path/1.xml").getPath());

    //7、obj.getClass().getResource("/com/path/1.xml")
    TestString = "obj.getClass().getResource(" + ""/com/path/1.xml"" +")";
    System.out.println(TestString + ">>>>>>>>" + obj.getClass().getResource("/com/path/1.xml").getPath());

    //8、获取文件的绝对地址(去掉路径前面的/)
    String absolutePath= new File(obj.getClass().getResource("/com/path/1.xml").getPath()).getAbsolutePath();
    System.out.println("absolutePath>>>>>>>>"+absolutePath);
    String path = new File(obj.getClass().getResource("/com/path/1.xml").getPath()).getPath();
    System.out.println("path>>>>>>>>"+path);
    String pathIntetor = new File(absolutePath).getPath();
    System.out.println("pathIntetor>>>>>>>>"+pathIntetor);

    //9、取WEB-INF路径下的文件
    String webInfPath = obj.getClass().getResource("/").getPath(); //得到classpath路径
    webInfPath = webInfPath.substring(0, webInfPath.length()- "classes/".length())+"web.xml";
    webInfPath = new File (webInfPath).getAbsolutePath();
    System.out.println("webInfPath>>>>>>>>"+webInfPath);

    //10、Thread类,得到的是claspath路径
    String threadPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    threadPath = new File(threadPath).getAbsolutePath();
    System.out.println("threadPath>>>>>>>>"+threadPath);

    //11、ClassLoader.getSystemResource("")

    String classLoaderPath = ClassLoader.getSystemResource("").getPath();

    //threadPath = new File(threadPath).getAbsolutePath();
    System.out.println("classLoaderPath>>>>>>>>"+classLoaderPath);

    }

     

    }

     

     

     

     

    终极path解决方案

     

    public class ResourceLoaderUtil{

     

    private static Log log = LogFactory.getLog(ResourceLoaderUtil.class);

    //向上寻址分隔符
    private final static String updest ="../";

    //向下寻址分隔符
    private final static String forwarddest= "/";

    /**
    * @Description:通过相对路径获取到制定的文件输入流
    * @param relativePath
    * @return
    * @throws MalformedURLException
    * @throws IOException
    * @author wangweifeng
    * @since:2014-10-24 下午04:23:55
    */
    public static InputStream getStream(String relativePath) throws MalformedURLException, IOException {
    return ResourceLoaderUtil.getStream(ResourceLoaderUtil.getExtendResource(relativePath));
    }

    /**
    * @Description:根据提供的URL,返回文件的流
    * @param url
    * @return
    * @throws IOException
    * @author wangweifeng
    * @since:2014-10-24 下午04:25:23
    */
    public static InputStream getStream(URL url) throws IOException {
    if (url != null) {
    return url.openStream();
    } else {
    return null;
    }
    }
    /**
    * @Description:根据相对地址获取到Properties文件
    * @param resource
    * @return
    * @author wangweifeng
    * @since:2014-10-24 下午04:38:42
    */
    public static Properties getProperties(String resource) {
    Properties properties = new Properties();
    try {
    properties.load(getStream(resource));
    } catch (IOException e) {
    throw new RuntimeException("couldn't load properties file '" + resource + "'", e);
    }
    return properties;
    }

    /**
    * @Description:根据相对地址返回制定资源文件
    * @param relativePath
    * @return
    * @author wangweifeng
    * @since:2014-10-24 下午04:53:07
    */
    public static File getFile(String relativePath) {
    try {
    File file = new File(ResourceLoaderUtil.getExtendResource(relativePath).getPath());
    return file;
    } catch (Exception e) {
    throw new RuntimeException("couldn't load file '" + relativePath + "'", e);
    }
    }

    /**
    * 思路:
    * 1、当前路径,或者classpath内寻址
    * 2、以"/"开始的寻址相对路径等于"",即从classpath路径开始
    * 3、处理"/"之后的寻址的相对路径,不含有向上寻址的可能性,直接用clasLoader寻址
    * 4、处理"/"之后的寻址的相对路径含有向上寻址符,则开始进行寻址逻辑
    **/
    public static URL getExtendResource(String relativePath) throws MalformedURLException {
    ResourceLoaderUtil.log.info("传入的相对路径:" + relativePath);
    URL resourceAbsoluteURL = null;
    // 不以"../"(向上)或以"/"(向下)开头,即取的是claspath路径下的文件
    if ((!relativePath.contains(updest)) && (!relativePath.startsWith(forwarddest))) { // 当前路基
    resourceAbsoluteURL = ResourceLoaderUtil.getResource(relativePath);
    System.out.println("相对寻址完成后路径为>>>>" + resourceAbsoluteURL);
    return resourceAbsoluteURL;
    }
    if (relativePath.substring(0, 1).equals(forwarddest)) {
    relativePath = relativePath.substring(1);
    if ("".equals(relativePath) || !(relativePath.contains(updest))) {
    return getExtendResource(relativePath);
    }
    }
    // 从classpath向下寻址
    String classPathAbsolutePath = ResourceLoaderUtil.getAbsolutePathOfClassLoaderClassPath();
    // 有效寻址路径
    String wildcardString = relativePath.substring(0, relativePath.lastIndexOf(updest) + updest.length());
    relativePath = relativePath.substring(relativePath.lastIndexOf(updest) + updest.length());

     

    classPathAbsolutePath = ResourceLoaderUtil.cutLastString(classPathAbsolutePath, wildcardString, updest);
    String resourceAbsolutePath = classPathAbsolutePath + relativePath;
    ResourceLoaderUtil.log.info("绝对路径:" + resourceAbsolutePath);
    resourceAbsoluteURL = new URL(resourceAbsolutePath);
    System.out.println("相对寻址完成后路径为>>>>" + resourceAbsoluteURL);
    return resourceAbsoluteURL;
    }

    /**
    * @Description:得到加载Java类,使用全限定类名。
    * @param className
    * @return
    * @author wangweifeng
    * @since:2014-10-24 下午01:15:39
    */
    private static Class loadClass(String className) {
    try {
    return getClassLoader().loadClass(className);
    } catch (ClassNotFoundException e) {
    throw new RuntimeException("class not found '" + className + "'", e);
    }
    }
    /**
    * @Description:得到类加载器
    * @return
    * @author wangweifeng
    * @since:2014-10-24 下午01:14:39
    */
    private static ClassLoader getClassLoader() {
    return ResourceLoaderUtil.class.getClassLoader();
    }

    /**
    *得到本Class所在的ClassLoader的Classpath的绝对路径。
    *URL形式的
    *@return
    */
    private static String getAbsolutePathOfClassLoaderClassPath() {
    ResourceLoaderUtil.log.info(ResourceLoaderUtil.getClassLoader().getResource("").toString());
    return ResourceLoaderUtil.getClassLoader().getResource("").toString();
    }

    /**
    * @Description:根据classLoader获取资源地址
    * @param resource
    * @return URL
    * @author wangweifeng
    * @since:2014-10-24 下午02:11:26
    */
    private static URL getResource(String resource) {
    ResourceLoaderUtil.log.info("传入的相对于classpath的路径:" + resource);
    return ResourceLoaderUtil.getClassLoader().getResource(resource);
    }

     


    /**
    * @descroption:相对寻址的核心方法
    * @param 根据relativePath中包含向上寻址部分,获兑正确地址
    * @param source == classPathAbsolutePath 相对地址
    * @param relativePath 部分相对地址 ../lib/../../
    * @param dest向上寻址分隔符,此处定义为../
    * @author wangweifeng
    * @since:2014-10-24 下午03:00:23
    */
    private static String cutLastString(String source, String partRelativePath, String dest) {
    if (partRelativePath.startsWith(dest)) {// 向上寻址一次
    source = source.substring(0, source.lastIndexOf("/", source.length() - 2) + 1);
    partRelativePath = partRelativePath.substring(dest.length());
    System.out.println(source);
    } else {
    String forWordPath = partRelativePath.substring(0, partRelativePath.indexOf(dest));
    partRelativePath = partRelativePath.substring(partRelativePath.indexOf(dest));
    source = source + forWordPath;
    System.out.println(source);
    }
    if (!"".equals(partRelativePath)) {
    cutLastString(source, partRelativePath, dest);
    }
    return source;
    }

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    一百多套开发视频教程的下载地址
    魅族MX3问题集锦
    Entity Framework 5问题集锦
    【PHP Manager for IIS】让IIS支持PHP
    MySQL安装
    phpMyAdmin安装
    犯了一个愚蠢的序列化错误
    最佳策略
    .net非托管资源
    .net内存何时回收?
  • 原文地址:https://www.cnblogs.com/richelle009/p/4053615.html
Copyright © 2020-2023  润新知