【文件處理】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中文件的相對路徑與絕對路徑

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