Java 路径问题最终解决
方案 前言 Java 的路径问题,非常难搞。最近的工作涉及到创建和读取文件的
工作,这里我就给大家彻底得解决 Java 路径问题。 我编写了一个方法, ClassLoader.getResource(String 相对路径)方法的能力更强。 比 它可以接受 “../” 这样的参数, 允许我们用相对路径来定位 classpath 外面的资源。这样,我们就可以使用相对于 classpath 的路径,定位所有位置的资源! Java 路径 Java 中使用的路径,分为两种:绝对路径和相对路径。具体而言,又分为四种: 一、URI 形式的绝对资源路径 如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b URL 是 URI 的特例。URL 的前缀/协议,必须是 Java 认识的。URL 可以打开资源,而 URI 则不行。 URL 和 URI 对象可以互相转换,使用各自的 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 的相对路径。 ClassLoader 类的 getResource(String name),getResourceAsStream(String name)等方法,使用相对于当前项目的 classpath 的相对路径来查找资源。 读取属性文件常用到的 ResourceBundle 类的 getBundle(String path)也是如此。 通过查看 ClassLoader 类及其相关类的源代码,我发现,它实际上还是使用了 URI 形式的绝对路径。通过得到当前 classpath 的 URI 形式的绝对路径,构 建了相对路径的 URI 形式的绝对路
径。 (这个实际上是猜想,因为 JDK 内部调用了 SUN 的源代码,而这些代码不属于 JDK,不是开源的。 ) 相对路径本质上还是绝对路径。因此,归根结底,Java 本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过 是 API 在底层帮助我们构建了绝对路径,从而找到资源的! 下面是一些得到 classpath 和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。 1,FileTest.class.getResource("") 得到的是当前类 FileTest.class 文件的 URI 目录。不包括自己! 如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/ 2,FileTest.class.getResource("/") 得到的是当前的 classpath 的绝对 URI 路径。 如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/ 3,Thread.currentThread().getContextClassLoader().getResource("") 得到的也是当前 ClassPath 的绝对 URI 路径。 如:file:/D:/java/