Java项目获取路径方法

Java项目中根据相对路径和绝对路径获取文件的方法(重要)

首先,项目中文件分布情况如下,innerFile.txt位于test.test包下,innerInnerFile.txt位于test.test.inner包下,outterFile.txt位于包的根目录下,

文件位置

那么,在App类里,如何根据相对路径、绝对路径获取innerFile.txt、innerInnerFile.txt和outterFile.txt呢?

class.getResource(name)

先来看一下Class.getResource(name)方法,该方法接收一个表示文件路径的参数,返回一个URL对象,该URL对象表示的name指向的那个资源(文件)。这个方法是在类中根据name获取资源。其中,name可以是文件的相对路径(相对于该class类来说),也可以是绝对路径(绝对路径的话,根目录符号/是代表项目路径而不是磁盘的根目录)。例如,如下两种根据路径获取文件的效果是一样的 :

  1. App.class.getResource('innerFile.txt')
  2. App.class.getResource('/test/test/innerFile.txt')

由于innerFile.txt和App类是在同一个包下,所以通过App.class和相对路径可以获取到App这个类的包下面的innerFile.txt文件。而当传入的是绝对路径/test/test/innerFile.txt,getResource()方法是从项目的包的根目录开始解析路径的。所以这两种获取文件的效果是一样的。

classLoader.getResource(name)

该方法的作用与class.getResource(name)的作用一样,接收一个表示路径的参数,返回一个URL对象,该URL对象表示name对应的资源(文件)。但是,与class.getResource(name)不同的是,该方法只能接收一个相对路径,不能接收绝对路径如/xxx/xxx。并且,接收的相对路径是相对于项目的包的根目录来说的。比如,如下两种获取文件的效果是一样的:

  1. App.class.getResource('innerFile.txt')
  2. App.class.getClassLoader().getResource('test/test/innerFile.txt')

classLoader.getResource('test/test/innerFile.txt')是相对于项目的包的根目录来解析路径的,所以通过该路径能够获取到innerFile.txt,并且不能传入绝对路径,否则报错。
介绍完了这两种,那么应该能够根据这两种方法分别获取到innerInnerFile.txt文件和outterFile.txt文件吧?

class.getResource(name)与classLoader.getResource(name)的联系

如上所述,class.getResource(name)能够接受相对路径和绝对路径,而classLoader.getResource(name)只能接收相对路径,那么这两种方法的联系是什么呢?

通过查看class.getResource(name)源码,可以看到,class.getResource(name)最终其实是通过classLoader.getResource(name)来获取资源文件的,如,

// class.getResource(name)方法
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);
}

其中,class.getResource(name)首先会对name进行解析和处理,如,

// class.getResource(path)中对path预处理path = resolveName(path)
private String resolveName(String name) {
    if (name == null) {
        return name;
    }
    if (!name.startsWith("/")) {
        Class<?> c = this;
        while (c.isArray()) {
            c = c.getComponentType();
        }
        String baseName = c.getName();  // 获取带包路径的类名,此处类名是App,包的路径是test.test,所以baseName就是test.test.App。
        int index = baseName.lastIndexOf('.');
        if (index != -1) {
            name = baseName.substring(0, index).replace('.', '/')  // 给参数加上当前类所在的包的路径前缀,即在name之前加上test/test,之后会委托给classLoader来getResource(path),而classLoader默认是从项目根路径获取资源的。
                +"/"+name;
        }
    } else {
        // path以'/'开头,则去掉开头的'/',采用classLoader.getResource(去掉开头'/'后的path)来获取资源。
        name = name.substring(1);
    }
    return name;
}

其中,如果传入的是绝对路径,那么去掉最前面的/,然后会委托给classLoader.getResource(name)处理;如果传入的是相对路径,那么首先获取到当前class类的完整包名,把包名中的.替换成/,也就是说,App类获取到包名是test.test.App,那么会被替换成test/test/App,然后委托给classLoader.getResource(name)处理。

总结

class.getResource(name)中name可以写成绝对路径/test/test/innerFile.txt和相对路径【假设该class位于test.test包下】”innerFile.txt”,其中绝对路径的/是相当于项目的classpath根目录,相对路径是相对于当前class的路径。classLoader.getResource(name)中的name一定要写成相对路径如test/test/innerFile.txt(最前面不能是/,并且这个相对路径是相对于项目的classpath根目录的路径,相当于class.getResource(name)中写绝对路径/test/test/innerFile.txt

这2个方法都是返回URL对象,接着可以通过getPath()方法获取String类型的路径:

this.getClass.getClassLoader().getResource('test/test/innerFile.txt').getPath()

可以通过这个方式直接获取输入流:

InputStream is = TemplateExcelUtils.class.getClassLoader().getResourceAsStream("template/"+sourcePath);

注意:class.getResource()和classLoader.getResource()获取的路径可以从项目根路径开始的,项目根路径指的是如图:(我们打包后的项目中,层级是下图所示的层级)

路径获取常用方法:

Javaweb的不常用方法:

以工程名为/DemoWeb为例:
访问的jsp为:http://localhost:8080/DemoWeb/test/index.jsp

1 JSP中获得当前应用的相对路径和绝对路径
(1)得到工程名:request.getContextPath()
结果:/DemoWeb

(2)得到包含工程名的当前页面全路径:request.getRequestURI()
结果:/DemoWeb/test/testpath.jsp

(3)得到IE地址栏地址:request.getRequestURL()
结果:http://localhost:8080/DemoWeb/test/testpath.jsp

(4)得到当前页面所在目录下全名称:request.getServletPath()
结果:/test/testpath.jsp

(5)得到页面所在服务器的全路径(实际的路径):application.getRealPath(“testpath.jsp”)
结果:D:\Develop Files\apache-tomcat-5.5.15\apache-tomcat-5.5.15\webapps\DemoWeb\testpath.jsp
D:\Develop Files\apache-tomcat-5.5.15\apache-tomcat-5.5.15为tomcat的安装路径

2.java 的Class中获得相对路径,绝对路径的方法

(1)类的绝对路径:
System.out.println(TestPath.class.getResource("/").getPath());
结果:/E:/workspace/workspace_tcc/DemoWeb/WebRoot/WEB-INF/classes/

System.out.println(TestPath.class.getResource(""));
结果:file:/E:/workspace/workspace_tcc/DemoWeb/WebRoot/WEB-INF/classes/demo1/

(2)得到工程的路径:System.getProperty(“user.dir”)
结果:E:\workspace\workspace_tcc\DemoWeb

(3)获取WEB-INF路径:request.getServletContext().getRealPath("/")           有误

结果:E:/workspace/workspace_tcc/DemoWeb/WebRoot/WEB-INF/

个人实践获取javaweb路径
this.getServletContext()和req.getServletContext()都是通过ServletContext()来获取路径
String realPath1 = this.getServletContext().getRealPath("/");
String realPath2 = this.getServletContext().getRealPath("/WEB-INF/upload");
String realPath3 = req.getServletContext().getRealPath("/");

System.out.println(realPath1);
System.out.println(realPath2);
System.out.println(realPath3);

结果:(项目名称:smbms)
E:\javaWEB\apache-tomcat-9.0.40\webapps\smbms\
E:\javaWEB\apache-tomcat-9.0.40\webapps\smbms\WEB-INF\upload
E:\javaWEB\apache-tomcat-9.0.40\webapps\smbms\

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值