首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 讀取資源檔案完全指南:相對路徑 vs Classpath 最佳實踐

     編輯:Java 相關知識

為什麼讀取檔案總是找不到?

Java 開發中讀取資源檔案失敗是常見痛點,根因在於執行環境不同導致「相對路徑」基準改變。本文系統梳理三種讀取方式,並給出生產環境可靠的最佳實踐。

專案目錄結構範例

repathtest
├─src
│ └─com
│   └─lavasoft
│     ├─test
│     └─res
├─doc

方式一:IDE 專案相對路徑(僅開發期有效)

File f = new File("src/com/lavasoft/res/a.txt");
File f = new File("doc/b.txt");
  • 路徑不以 / 開頭
  • 基準目錄 = 專案根目錄(repathtest)
  • 缺點:脫離 IDE(如打包部署)即失效,生產環境不可用

方式二:Classpath 讀取包內資源(推薦)

InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");
  • 路徑必須以 / 開頭,表示 classpath 根目錄
  • 適用於 src/main/resources 或編譯輸出目錄(target/classes)下的檔案
  • 優點:開發、測試、打包部署(JAR/WAR)均正常運作

完整測試程式碼

package com.lavasoft.test;
import java.io.*;

public class ReadFile {
    public static void main(String[] args) {
        readTextA_ByClassPath();
        readTextA_ByProjectRelativePath();
        readTextB_ByProjectRelativePath();
    }

    // 專案相對路徑讀取包內檔案
    public static void readTextA_ByProjectRelativePath() {
        File f = new File("src/com/lavasoft/res/a.txt");
        System.out.println(file2String(f, "GBK"));
    }

    // 專案相對路徑讀取包外檔案
    public static void readTextB_ByProjectRelativePath() {
        File f = new File("doc/b.txt");
        System.out.println(file2String(f, "GBK"));
    }

    // Classpath 讀取包內檔案
    public static void readTextA_ByClassPath() {
        InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");
        System.out.println(stream2String(in, "GBK"));
    }

    // 工具方法:File -> String
    public static String file2String(File f, String charset) {
        try { return stream2String(new FileInputStream(f), charset); }
        catch (FileNotFoundException e) { e.printStackTrace(); return null; }
    }

    // 工具方法:InputStream -> String
    public static String stream2String(InputStream in, String charset) {
        StringBuilder sb = new StringBuilder();
        try (Reader r = new InputStreamReader(in, charset)) {
            char[] buf = new char[1024];
            for (int len; (len = r.read(buf)) != -1; ) sb.append(buf, 0, len);
        } catch (IOException e) { e.printStackTrace(); }
        return sb.toString();
    }
}

執行結果對比

-----------------readTextA_ByClassPath---------------------
aaaaaaaaa
sssssssss
-----------------readTextA_ByProjectRelativePath---------------------
aaaaaaaaa
sssssssss
-----------------readTextB_ByProjectRelativePath---------------------
bbbbbbbbbbb

IDE 中三種方式均成功,但脫離 IDE 僅 Classpath 方式存活。

進階:取得 Classpath 資源的絕對路徑(寫入檔案時需用)

// 當前類輸出目錄
Test.class.getResource("/").getFile()
// 指定資源絕對路徑
Test.class.getResource("/com/lavasoft/cfg/syscfg.properties").getFile()
new File(Test.class.getResource(cp).getFile()).getPath()

輸出範例:D:\projects\...\out\production\...\com\lavasoft\cfg\syscfg.properties

總結:生產環境唯一可靠原則

所有需隨應用部署的資源檔案,必須放入 Classpath(src/main/resources),使用 Class.getResourceAsStream("/path") 讀取。

  • 專案相對路徑:不可靠,僅適合 IDE 臨時測試
  • Classpath 路徑:標準、可移植、生產就緒

IDEA 運行配置示意圖

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved