【文件处理】java中文件的相对路径与绝对路径

1. 前言

下面的corejava项目下,labs-v2ch02模块下,有4个文件,1.properties、2.properties、3.properties、4.properties。
当我们需要使用这4个文件的时候,怎样创建文件对象呢?
在这里插入图片描述

2. 基本知识

(1) 不同的操作系统,文件的分隔符不同:
Linux下:”/”
Window下:”\”
Java中通用表示方法:System.getProperty(“file.separator”);

(2) java.io.*包下,File以及Path,只是文件或路径的抽象表示,并不一定实际存在。
如 File file = new File(“a.txt”); 表示在jvm启动路径下,新建a.txt文件,在写入文件前,并不存在。

(3) 相对路径指的是相对JVM的启动路径。
举个例子:假设有一java源文件Example.java在d盘根目录下。我们进入命令行窗口,进入到d盘根目录下,然后用“javac Example.java”来编译此文件,编译无错后,会在d盘根目录下自动生成”Example.class”文件。我们再调用”java Example”来运行该程。此时我们已经启动了一个jvm,这个jvm是在d盘根目录下被启动的,所以此jvm所加载的程序中File类的相对路径也就是相对这个路径的,即d盘根目录D:\。
搞清了这些,我们可以使用相对路径来创建文件,例如:
File file = new File(“a.tx”);
file.createNewFile();
假设jvm是在”D:\”下启动的,那么a.txt就会生成在D:\a.txt;

2. 获取源码路径下文件

前面我们说过,JAVA中文件路径是相对JVM的启动路径的,对于简单的JAVA项目,其JVM是在项目名称下启动的。“.”或”./”代表当前目录,这个目录也就是jvm启动路径。

package com.geo.v2ch02;

import java.io.File;

/**
 * 获取模块下文件
 * @author galen
 * @date 2020-4-18
 * */
public class modelPath {
    public static void main(String[] args) {
        try {
            // "./"表示默认启动路径,即jvm路径,对于简单项目,JVM是在项目名称下启动的,
            File file1 = new File("./labs-v2ch02/1.properties");

            File file2 = new File("./labs-v2ch02/src/2.properties");

            File file3 = new File("./labs-v2ch02/src/com/geo/v2ch02/3.properties");

            File file4 = new File("./labs-v2ch02/src/com/geo/v2ch02/sub/4.properties");

            System.out.println(file1.exists() + ",file1:" + file1.getCanonicalPath());
            System.out.println(file2.exists() + ",file2:" + file2.getCanonicalPath());
            System.out.println(file3.exists() + ",file3:" + file3.getCanonicalPath());
            System.out.println(file4.exists() + ",file4:" + file4.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果(注意获取到的都是源码路径下的文件):
在这里插入图片描述

3. 获取父级路径

“.”或”./”代表当前目录,这个目录也就是jvm启动路径。"…\"、"…/"代表当前目录的上级目录,getParent()代表当前文件或目录的上级目录。

package com.geo.v2ch02;

import java.io.File;

/**
 * 获取模块下文件
 * @author galen
 * @date 2020-4-18
 * */
public class parentPath {
    public static void main(String[] args) {
        try {
            //注意".\\"与"./"在这里效果一样,建议用"./"与生产环境(一般为linux)语义一致
            File file5 = new File(".\\test1.txt");
            File file6 = new File("./test1.txt");

            File file7 = new File("..\\test1.txt");
            File file8 = new File("../test1.txt");
            File file9 = new File(file8.getParent()+"/test1.txt");

            System.out.println(file5.exists() + ",file5:" + file5.getCanonicalPath());
            System.out.println(file6.exists() + ",file6:" + file6.getCanonicalPath());
            System.out.println(file7.exists() + ",file7:" + file7.getCanonicalPath());
            System.out.println(file8.exists() + ",file8:" + file8.getCanonicalPath());
            System.out.println(file9.exists() + ",file9:" + file9.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果:注意观察输出的文件路径。
在这里插入图片描述

4. 获取发布目录下文件

上面创建文件的方式太过于繁琐,所以对于package内的文件,我们采用getResource()、或者getClassLoader().getResource()获取,对于2.properties和2.properties的获取,我们倾向于采取下面的方法:
File file2 = new File(getResourcePath.class.getResource("/2.properties").toURI());
File file3 = new File(getResourcePath.class.getResource(“3.properties”).toURI());
或者:
File file4 = new File(getResourcePath.class.getClassLoader().getResource("").toURI());
File file5 = new File(getResourcePath.class.getClassLoader().getResource(“com/geo/v2ch02/3.properties”).toURI());

package com.geo.v2ch02;

import java.io.File;

/**
 * 获取模块下文件
 * @author galen
 * @date 2020-4-18
 * */
public class getResourcePath {
    public static void main(String[] args) {
        try {
            //path  不以’/'开头时,默认是从此类所在的包下取资源;path  以’/'开头时,则是从ClassPath根下获取;
            File file2 = new File(getResourcePath.class.getResource("/2.properties").toURI());
            File file3 = new File(getResourcePath.class.getResource("3.properties").toURI());

            //使用class.getClassLoader(),当目录或者文件不存在时,会报错
            File file4 = new File(getResourcePath.class.getClassLoader().getResource("").toURI());
            File file5 = new File(getResourcePath.class.getClassLoader().getResource("com/geo/v2ch02/3.properties").toURI());
            System.out.println(file2.exists() + ",file2:" + file2.getCanonicalPath());
            System.out.println(file3.exists() + ",file3:" + file3.getCanonicalPath());
            System.out.println(file4.exists() + ",file4:" + file4.getCanonicalPath());
            System.out.println(file5.exists() + ",file5:" + file5.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果:
在这里插入图片描述
从结果来看【TestMain.class.getResource("/") == t.getClass().getClassLoader().getResource("")】

对于web项目 springmvc【未验证】
Tomcat中的情况,如果在tomcat中运行web应用,此时,如果我们在某个类中使用如下代码:
File f = new File(".");
String absolutePath = f.getAbsolutePath();
System.out.println(absolutePath);
那么输出的将是tomcat下的bin目录.我的机器就D:\Java\apache-tomcat-8.5.32-windows-x64\apache-tomcat-8.5.32\bin.,由此可以看出tomcat服务器是在bin目录下启动jvm的,其实是在bin目录下的“catalina.bat”文件中启动jvm的。

对于web项目 springboot框架
对于springboot项目,输出路径为配置的target/classes目录
在这里插入图片描述
在这里插入图片描述

5. getPath()、getAbsolutePath()、getCanonicalPath()的区别

getPath()获取的是新建文件时的路径,例如:
File file1 = new File(".\test1.txt");通过getPath()获取的是.\test1.txt

File file2 = new File(“D:\Text.txt”);通过getPath()获取的是D:\Text.txt

getAbsolutePath()获取的是文件的绝对路径,返回当前目录的路径+构造file时候的路径,例如:
File file3 = new File(".\test1.txt");通过getAbsolutePath()获取的是D:\open source\gitee\corejava.\test1.txt

getCanonicalPath()获取的也是文件的绝对路径,而且把…或者.这样的符号解析出来,例如:
File file4 = new File("…\src\test1.txt");通过getCanonicalPath()获取的是D:\open source\gitee\src\test1.txt

package com.geo.v2ch02;

import java.io.File;

/**
 * 获取模块下文件
 * @author galen
 * @date 2020-4-18
 * */
public class testPath {
    public static void main(String[] args) {
        try {
            File file1 = new File(".\\test1.txt");
            File file2 = new File("D:\\Text.txt");
            File file3 = new File(".\\test1.txt");
            File file4 = new File("..\\src\\test1.txt");

            System.out.println("file1:" + file1.getPath());
            System.out.println("file2:" + file2.getPath());
            System.out.println("file3:" + file3.getAbsolutePath());
            System.out.println("file4:" + file4.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
本文源码地址:
java基础 corejava

本文多参考:
Java中文件的相对路径与绝对路径

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章