new File("C:\\Users\\Admin\\Documents\\data.txt") 顯示無誤。java.io.FileNotFoundException,但文件明確存在。Windows 為支持 RTL (右到左) 語言 (阿拉伯語、希伯來語),在文件路徑中自動插入 LRE (Left-to-Right Embedding, U+202A) 或 RLE (U+202B) 等雙向文本控制字符。這些字符:
File 構造器將其視為合法路徑字符,導致實際路徑不匹配。<!DOCTYPE html>
<html><body>
<script>
// 將複製的路徑字符串粘貼到此處
const raw = "C:\\Users\\Admin\\Documents\\data.txt"; // 實際粘貼內容
for (let i = 0; i < raw.length; i++) {
console.log(i, raw[i], raw.charCodeAt(i).toString(16).toUpperCase().padStart(4,'0'));
}
</script>
</body></html>
輸出中若出現 202A (LRE) 或 202B (RLE) 即確認攜帶控制字符。
str.replace(/[\u200E\u200F\u202A-\u202E]/g, '')。public static String sanitizePath(String raw) {
// 移除所有雙向控制字符: LRE(202A) RLE(202B) PDF(202C) LRO(202D) RLO(202E) LRM(200E) RLM(200F)
return raw.replaceAll("[\\u200E\\u200F\\u202A-\\u202E]", "");
}
// 使用
String raw = "C:\\Users\\Admin\\Documents\\data.txt"; // 含隱形字符
File file = new File(sanitizePath(raw));
編碼 → 以 UTF-8 無 BOM 編碼 → 視圖 → 顯示符號 → 顯示所有字符,控制字符顯示為 LRE/RLE。Render Whitespace / Control Characters 擴展,或設置 "editor.renderControlCharacters": true。| 規則 | 說明 |
|---|---|
| 禁用字符 | \ / : * ? " < > | 及控制字符 (0x00-0x1F, 0x202A-0x202E) |
| 保留名 | CON, PRN, AUX, NUL, COM1-9, LPT1-9 等不可作為文件名 |
| 最大長度 | 路徑 260 字符 (MAX_PATH),啟用長路徑支持可突破 |
| 大小寫不敏感 | NTFS 大小寫保留但不敏感,Java 路徑匹配需注意 |
Windows 路徑複製帶入的 Unicode 雙向控制字符 (U+202A LRE 等) 是 Java FileNotFoundException 反覆發生的隱形殺手。通過 源頭規避複製源、編輯器可視化檢測、代碼統一清洗 三重防線,可徹底根治此類「明明文件存在卻找不到」的靈異問題。建議團隊將路徑清洗工具方法納入公共庫,新員工入職必講此坑。