一、前言

之前一直对于java中的路径是模棱两可的感觉,对这一块,看似知道,其实也不知道。每次遇到FileNotFound的时候就会去Google去查询,这个方法怎么用哇,到底相对路径指的是从哪开始的路径呀,等等问题!其实就是在蒙答案,按照编程中的说法就是撞大运式的编程,这次争取一次性的搞懂java中的路径问题,争取以后编程心中有丘壑。

二、相对路径和绝对路径

绝对路径:绝对路径的英文全称是Absolute Path,就是真实的路径,是计算机中完整路径,必须准确,否则不能找到,起点是系统的根目录,也就是各个盘符

相对路径:所谓相对路径,就是相对于自己的目标文件位置。但是相对路径最重要是相对的概念,到底相对的是项目的根目录还是classpath目录

这样说了可能感觉不大,那下面就举出一个具体的例子来说明什么是绝对路径,什么是相对路径
image.png
那么javaIO模块下的resoure目录下的 a.txt文件,它的绝对路径和相对路径如下:

绝对路径:D:\code\River\JavaSE\javaIO\src\main\resources\a.txt
相对路径:相对于项目的根路径是:classpath(也就是我们看到的 target/classes** )

三、File类中的路径

在project中,相对路径的根目录是project的根文件夹,创建文件的写法是:

相对路径:相对的是:D:\code\River\JavaSE(也就是工程的相对路径),注意路径不能以”/“开头

  1. private static void filePath() {
  2. File file = new File("javaIO/src/main/java/org/huanghe/stream/Java中字符流与字节流的区别.md");
  3. System.out.println(file.exists());
  4. System.out.println(System.getProperty("user.dir"));
  5. }

绝对路径:

  1. private static void filePath() {
  2. File file = new File("D:\code\River\JavaSE\javaIO\src\main\java\org\huanghe\stream\Java中字符流与字节流的区别.md");
  3. System.out.println(file.exists());
  4. System.out.println(System.getProperty("user.dir"));
  5. }

四、获取文件的路径class.getResource和class.getClassLoader

在我们Java开发中往往需要去获取文件中的内容,一般的我们会使用File的形式获取,如:我要获取“c:\文件.txt”此时我们需要创建一个File的对象File file=new FIle(“c:\文件txt”);

然后在使用file类创建一个文件文件输入流 :FileInputStream in =new FileInputStream(file),然后再是使用该输入流进行我们想要的操作,但是这样有一个弊端,就是我们的文件路径是一种硬编码的形式,在Java编码过程中我们极其不推荐这种写法

当然在web项目下,我们可以通过application对象的getRealPath(“文件名”)的方式获取文件的绝对路径,但是这样也不是很推荐,因此我们可以使用class.getResource(path)和class.getClassLoader(path)方法来获取文件资源,那么我们来研究一下两者的区别:

4.1 class.getResource(path)

其中的参数path有两种形式,一种是以“/”开头的,另一种是不以”/“开头;

  • 以’/‘开头的表示:从项目的根路径下去获取文件即classPath目录下
  • 不以”/“开头:以该类对象所在位置为根路径来进行查找的


  1. /**
  2. * 测试class.getResource获取文件路径
  3. */
  4. public static void testClassGetResource() {
  5. System.out.println(_01_JavaFilePath.class.getResource(""));
  6. System.out.println(_01_JavaFilePath.class.getResource("/"));
  7. }

输出的结果为:

:::info file:/D:/Code/JavaSE/io/target/classes/com/huanghe/chapter/ : 返回的是 testClassGetResource.class这个类所在的目录
file:/D:/Code/JavaSE/io/target/classes/ : 返回的是 项目的classpath目录的路径 :::

假设现在的项目结构如下所示,针对下面的三种情况如何获取:
image.png

获取上图所示的三种文件的方法:

  1. /**
  2. * 测试class.getResource获取文件路径
  3. */
  4. public static void testClassGetResource2() {
  5. System.out.println(_01_JavaFilePath.class.getResource("file/test.properties"));
  6. System.out.println(_01_JavaFilePath.class.getResource("../txt/01-java-filepath.txt"));
  7. System.out.println(_01_JavaFilePath.class.getResource("/01-java-filepath.txt"));
  8. }

输出的结果为:

:::success file:/D:/Code/JavaSE/io/target/classes/com/huanghe/chapter/one/file/test.properties

file:/D:/Code/JavaSE/io/target/classes/com/huanghe/chapter/txt/01-java-filepath.txt

file:/D:/Code/JavaSE/io/target/classes//01-java-filepath.txt :::

📢: class.getResource()和class.getResourceAsStream()方式的使用在路径上是一致的。
**

4.2 Class.getClassLoader().getResource(String path)

该方法中的参数path不能以“/“开头,path表示的是从classpath下获取资源的

  1. package testpackage;
  2. public class TestMain {
  3. public static void main(String[] args) {
  4. TestMain t = new TestMain();
  5. System.out.println(t.getClass());
  6. System.out.println(t.getClass().getClassLoader());
  7. System.out.println(t.getClass().getClassLoader().getResource(""));
  8. System.out.println(t.getClass().getClassLoader().getResource("/"));//null
  9. }
  10. }

输出结果:

:::info

  1. class testpackage.TestMain
  2. sun.misc.Launcher$AppClassLoader@1fb8ee3
  3. file:/D:/Code/JavaSE/io/target/classes
  4. null
    :::

    五、总结

  5. 使用工程相对路径是靠不住的。
    2. 使用CLASSPATH路径是可靠的。
    3. 对于程序要读取的文件,尽可能放到CLASSPATH下,这样就能保证在开发和发布时候均正常读取。