1. 程式人生 > >JAVA獲取資源路徑、建立檔案物件

JAVA獲取資源路徑、建立檔案物件

一、Java專案中建立檔案物件

下面是一個java專案,名稱為ResourceTest。在這個專案中有4個檔案,1.properties、2.properties、3.properties、4.properties。
這裡寫圖片描述

編譯完成後,這4個檔案的路徑如下:
…ResourceTest/1.properties
…ResourceTest/bin/2.properties
…ResourceTest/bin/com/ghs/test/3.properties
…ResourceTest/bin/com/ghs/test/sub/4.properties

所以,我們可以通過下面的程式碼來為這4個檔案建立File物件,其中,”.”或者”./”表示當前目錄,也就是JVM的啟動目錄。

public class MainTest {
    public static void main(String[] args) {

        File file1 = new File("./1.properties");
        //File file1 = new File("test1.txt");

        File file2 = new File("./bin/2.properties");
        //File file2 = new File("bin/2.properties");

        File file3 = new File("./bin/com/ghs/test/3.properties"
); //File file3 = new File("bin/com/ghs/test/3.properties"); File file4 = new File("./bin/com/ghs/test/sub/4.properties"); //File file4 = new File("bin/com/ghs/test/sub/4.properties"); try { System.out.println(file1.exists()+":"+file1.getCanonicalPath()); System.out
.println(file2.exists()+":"+file2.getCanonicalPath()); System.out.println(file3.exists()+":"+file3.getCanonicalPath()); System.out.println(file4.exists()+":"+file4.getCanonicalPath()); } catch (IOException e) { e.printStackTrace(); } } }

執行結果如下:
true:D:\me\open\open-project\ResourceTest\1.properties
true:D:\me\open\open-project\ResourceTest\bin\2.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\sub\4.properties

二、WEB專案中建立檔案物件

下面的是一個Java Web專案,名稱為ResourceWeb。這個專案下同樣有4個檔案:1.properties、2.properties、3.properties、4.properties。
這裡寫圖片描述

編譯完成後,這4個檔案的路徑如下:
…/ResourceWeb/1.properties
…/ResourceWeb/build/classes/2.properties
…/ResourceWeb/build/classes/com/ghs/test/3.properties
…/ResourceWeb/build/classes/com/ghs/test/sub/4.properties

所以,我們可以通過下面的程式碼來建立web專案的檔案物件。

public class MainTest {

    public static void main(String[] args) {

        File file1 = new File("./1.properties");
        //File file1 = new File("test1.txt");

        File file2 = new File("./build/classes/2.properties");
        //File file2 = new File("build/classes/2.properties");

        File file3 = new File("./build/classes/com/ghs/test/3.properties");
        //File file3 = new File("build/classes/com/ghs/test/3.properties");

        File file4 = new File("./build/classes/com/ghs/test/sub/4.properties");
        //File file4 = new File("build/classes/com/ghs/test/sub/4.properties");

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

執行結果如下:
true:D:\me\open\open-project\ResourceWeb\1.properties
true:D:\me\open\open-project\ResourceWeb\build\classes\2.properties
true:D:\me\open\open-project\ResourceWeb\build\classes\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceWeb\build\classes\com\ghs\test\sub\4.properties

細心的你肯定會發現,由於專案的性質不同,位置相同的檔案,路徑也會不一樣。不過,如果你再細心一點,還會發現,這種不一樣僅僅在於檔案編譯後的根目錄。
所以,為了保證資源讀取的統一性,Java提供了通用的資源讀取方式,使得我們不用關心專案編譯後文件的根目錄。他們就是通過類、類載入器讀取資源。

三、通過類/類載入器讀取資源

同樣是上面的Java專案,我們通過類載入器(ClassLoader)讀取資源,程式碼如下:

public class ClassLoaderReaderTest {
    public static void main(String[] args) {
        try {
            ClassLoader loader = ClassReaderTest.class.getClassLoader();
            File file2 = new File(loader.getResource("2.properties").toURI());
            System.out.println(file2.exists()+":"+file2.getCanonicalPath());

            File file3 = new File(loader.getResource("com/ghs/test/3.properties").toURI());
            System.out.println(file3.exists()+":"+file3.getCanonicalPath());

            File file4 = new File(loader.getResource("com/ghs/test/sub/4.properties").toURI());
            System.out.println(file4.exists()+":"+file4.getCanonicalPath());

            File file1 = new File(loader.getResource("../1.properties").toURI());
            System.out.println(file1.exists()+":"+file1.getCanonicalPath());

        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}

執行結果如下:
true:D:\me\open\open-project\ResourceTest\bin\2.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\sub\4.properties
java.lang.NullPointerException
at com.ghs.test.ClassReaderTest.main(ClassReaderTest.java:17)

我們會發現,通過ClassLoader讀取資源的時候,當前路徑就是專案檔案編譯後的根目錄,對於普通Java專案而言,就是…/bin目錄,對於web專案而言,就是…/build/classes目錄。
但是,當我們在讀取第一個檔案的時候丟擲了異常,這並不是因為我們的路徑錯了,而是因為1.properties不在類載入的範圍之類。也就是說,類載入器能夠讀取到的資源僅僅侷限於編譯後的根目錄。

下面,我們再使用類(Class)來讀取資源,程式碼如下:

public class ClassLoaderReaderTest {
    public static void main(String[] args) {
        try {
            Class clazz = ClassReaderTest.class;
            File file2 = new File(clazz.getResource("/2.properties").toURI());
            System.out.println(file2.exists()+":"+file2.getCanonicalPath());

            File file3 = new File(clazz.getResource("3.properties").toURI());
            System.out.println(file3.exists()+":"+file3.getCanonicalPath());

            File file4 = new File(clazz.getResource("sub/4.properties").toURI());
            System.out.println(file4.exists()+":"+file4.getCanonicalPath());

            File file1 = new File(clazz.getResource("../1.properties").toURI());
            System.out.println(file1.exists()+":"+file1.getCanonicalPath());

        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}

執行結果如下:
true:D:\me\open\open-project\ResourceTest\bin\2.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\sub\4.properties
java.lang.NullPointerException
at com.ghs.test.ClassReaderTest.main(ClassReaderTest.java:17)

當我們通過類載入資源時,當前路徑就是當前類所在的路徑,對上面的例子來說,就是MainTest.class所在的路徑。當載入資源時,如果在路徑前面加上”/”,就跟通過ClassLoader載入資源時完全一樣的。
同樣的,通過類載入資源時,僅限於專案編譯後的根目錄下的資源。