Java中的路径问题实例分析

前言:关于Java中得路径问题,网上有很多获取的答案,我这篇文章的目的在于说明获取路径时一些不常见的概念。在实际应用中使用的比较多的就是,当前路径和配置文件的路径(其他文件的路径)。为了搞清楚路径的问题我们不得不高清吃另一个问题, 那就是上下文Context, 我们可能听过很多关于上下文的问题, 比如说sevletContext,applicationContext,httpContext,, springContext上下文很多,那么究竟什么是上下文呢?

java中的上下文

Java中的上下文我们用到的地方非常多,比如说获取路径,资源定位,web项目启动。但是我们只是知道有这么一个东西充满了神秘感,而不知道它是什么。其实Context是一个抽象的概念,而不是确实存在的东西, 不像对象一样是一个实质的概念,<font color=red>我们可以这样理解,他就是一个环境,举个例子:在web项目中,我们将项目部署到了tomcat服务器中,而tomcat服务器同时也是一个容器,当我们想获取容器里面的东西的时候,却获取不到,这时候Context就出现了, 它的上层就是容器本身,同时它包含了容器创建的和我们创建的所有东西,我们可以通过Context获取我们想要的东西:例如资源位置。</font>可以这样想我们下了一个定义叫地球边界,我们人为的规定了它,它包含着整个地球里所有的东西,但是它却并不是真实存在的,我们却这样去用它们来获取一些东西,比如喜马拉雅山海拔8848米。大气层的高度是65000千米高等等。

这个上下文好似一双无形的手,把所有的对象,组件囊括其中。

当前路径

ClassLoader

在获取当前路径前我们还必须要搞懂一样东西就是类加载器,java的类加载机制(jvm规范)是委托模型,简单的说,如果一个类加载器想要加载一个类,首先它会委托给它的parent去加载,如果它的所有parent都没有成功的加载那么它才会自己亲自来。所以当我们使用到类加载器的时候就获取一定是该类的执行路径,也就是编译后路径,也就是 .class文件的路径。

  1. 通过getResource()来获取路径。

    public java.net.URL getResource(String name) {

       name = resolveName(name);
       ClassLoader cl = getClassLoader0();
       if (cl==null) {
           // A system class.
           return ClassLoader.getSystemResource(name);
       }
       return cl.getResource(name);

    }

在这里源码中写道 return ClassLoader.getSystemResource(name);它自动调用了类加载器的方法。所以也会是一个编译后路径,而我们在web项目中也是将项目编译后放入tomcat中得,所以当项目运行时找这个路径也是符合情理的。例如:

    String currentPath1 = PathTest.class.getResource("").getPath();
    System.out.println("当前类路径为1:" + currentPath1);
    String currentPath2 = PathTest.class.getClassLoader().getResource("").getPath();
    System.out.println("当前类路径为2:" + currentPath2);
    String currentPath3 = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    System.out.println("当前类路径为3:" + currentPath3);

它们的结果是:

当前类路径为1:/E:/IdeaWorkspace/path-analysis/out/production/path-analysis/testOthers/
当前类路径为2:/E:/IdeaWorkspace/path-analysis/out/production/path-analysis/
当前类路径为3:/E:/IdeaWorkspace/path-analysis/out/production/path-analysis/

另外sevlet中可以通过ServletContext来获取路径:


 String path = ServletContext.class.getClassLoader().getResource("").getPath();
    String path2 = ServletContext.class.getResource("/").getPath();

  System.out.println(path);
  System.out.println(path2);
这是结果:注意上面的getClassLoader(),一个有一个没有;
/E:/IdeaWorkspace/path-analysis/out/production/path-analysis/
/E:/IdeaWorkspace/path-analysis/out/production/path-analysis/
  1. 注意:上面的结果还有些不同直接通过getResource()得到的才是包含包名的类路径。
  2. 获取项目根路径的方法为:就这直接在getResource("/")这个方法中加上了根路径符。

配置文件的路径

可以通过这种方式来获取配置文件的路径,加上配置文件的相对路径名就好了:

String currentPath3 = Thread.currentThread().getContextClassLoader().getResource("resource/file.txt").getPath();
        System.out.println("当前类路径为3:" + currentPath3);

结果为:

当前类路径为3:/E:/IdeaWorkspace/path-analysis/out/production/path-analysis/resource/file.txt

获取配置文件的路径名在spring和其他框架中又有其他方式,这里不做过多说明了,网上教程一大堆。


Andy
54 声望11 粉丝

Remember,Hope is a good thing,maybe the best of things and no good thing ever dies!