Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 下 Java 讀取中文檔名亂碼問題完整解決方案

編輯:Linux 教學

問題現象

Linux 預設編碼為 UTF-8,檔案系統儲存中文檔名無問題。但 Java 程式用 File.listFiles() 讀取時,中文檔名顯示為 ????? 或亂碼。嘗試 new String(name.getBytes("GB2312"), "UTF-8") 反而全變 ?????。

根本原因

  • Java 內部使用 UTF-16(char),String.getBytes(charset) 是「按指定編碼**編碼**為位元組」,new String(bytes, charset) 是「按指定編碼**解碼**為字串」。
  • 若檔案系統實際編碼為 UTF-8,但 JVM 預設編碼(file.encoding)非 UTF-8(如 ISO-8859-1),則 File.getName() 回傳的字串已經在錯誤編碼下解碼完成,**資訊已遺失**,後續轉碼無法挽回。

正確解決路徑

方案一:啟動 JVM 時強制指定 UTF-8(推薦)

java -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -jar your-app.jar
  • file.encoding:影響 new String(bytes)、String.getBytes() 預設編碼。
  • sun.jnu.encoding:影響 File、FileInputStream 等檔案系統 API 的編碼(JDK 內部屬性)。

亦可在程式碼最早處呼叫 System.setProperty("file.encoding", "UTF-8"),**但必須在任何檔案操作前**,且不保證所有 JDK 版本生效,啟動參數最穩妥。

方案二:容器/伺服器環境設定 Locale

# /etc/locale.gen 取消註解 en_US.UTF-8 UTF-8
locale-gen
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

確保 locale 輸出皆為 UTF-8,JVM 啟動會自動採用。

方案三:程式碼層面顯式指定編碼(僅適用已知編碼)

// 讀取目錄
File dir = new File("/path");
File[] files = dir.listFiles();
for (File f : files) {
    // 若確定檔案系統為 UTF-8,直接用
    String name = f.getName(); // 已正確解碼
    // 若需轉為 bytes 再處理
    byte[] utf8Bytes = name.getBytes(StandardCharsets.UTF_8);
}

切勿**自行用 getBytes("GB2312") 等錯誤編碼再轉碼,會造成二次損壞。

驗證方式

public class EncodingTest {
    public static void main(String[] args) {
        System.out.println("file.encoding=" + System.getProperty("file.encoding"));
        System.out.println("sun.jnu.encoding=" + System.getProperty("sun.jnu.encoding"));
        System.out.println("defaultCharset=" + java.nio.charset.Charset.defaultCharset());
    }
}

輸出皆為 UTF-8 即正確。

常見誤區總結

錯誤做法後果正確做法
new String(name.getBytes("GB2312"), "UTF-8")雙重錯誤編碼,資訊永久遺失JVM 啟動參數指定 UTF-8
依賴預設編碼跨平台部署時行為不一致顯式指定 StandardCharsets.UTF_8
只設 file.encoding檔案系統 API 仍可能亂碼同時設 sun.jnu.encoding

只要在 JVM 啟動階段鎖定 UTF-8,Linux 下 Java 處理中文檔名即可徹底告別亂碼。

Copyright © Windows教程網 All Rights Reserved