首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java FTP 上傳失敗:FileNotFoundException 路徑含隱形字元排查實戰

     編輯:程式設計疑難解答

錯誤現場

java.io.FileNotFoundException: ‪D:\1.txt (文件名、目錄名或卷標語法不正確)

乍看路徑 D:\1.txt 沒問題,但異常訊息前的 ‪(Unicode **U+202A LEFT-TO-RIGHT EMBEDDING**,一個不可见的雙向文字控制字元)暴露真相:**原始碼字串字面量混入了隱形字元**。

根因分析

  1. 程式碼可能從網頁、Word、PDF 複製而來,帶入了 U+202A、U+202B、U+202C、U+200E、U+200F 等雙向標記或零寬空格(U+200B)。
  2. Java 原始碼編譯時將這些字元保留在字串常量中,new File("‪D:\\1.txt") 實際路徑以隱形字元開頭,Windows 檔案系統不認得,拋出「語法不正確」。
  3. 控制台輸出時隱形字元不顯示,肉眼難以發現。

快速排查步驟

  1. IDE 檢視: IntelliJ IDEA / Eclipse 開啟 Show Whitespaces(通常在 View → Active Editor → Show Whitespaces),隱形字元會顯示為紅點或特殊符號。
  2. 十六進位檢視: 在 IDE 中對字串字面量按 Ctrl+Shift+A 輸入 Show Hex,或用線上工具(如 https://www.onlinehextools.com/convert-string-to-hex)貼上字串檢查是否含 202A、200B 等。
  3. 程式碼驗證: 加入檢查邏輯:
    String path = "‪D:\\1.txt"; // 你的字串
    for (int i = 0; i < path.length(); i++) {
        char c = path.charAt(i);
        if (c < 32 || c == 0x200B || c == 0x202A || c == 0x202B || c == 0x202C) {
            System.out.printf("Hidden char at %d: U+%04X%n", i, (int)c);
        }
    }
    

解決方案

  • 重新手打路徑: 刪除原字串字面量,**手動逐字輸入** "D:\\1.txt"(雙反斜桿轉義)或 "D:/1.txt"(Java 支援正斜桿跨平台)。
  • 使用 Path / Paths.get (NIO.2):
    Path path = Paths.get("D:", "1.txt"); // 自動處理分隔符,避免字串拼接錯誤
    File file = path.toFile();
    
  • 清理專案原始碼: 用腳本掃描所有 .java 檔,移除 [\u2000-\u206F\uFEFF\uFFF0-\uFFFF] 範圍內的控制字元(保留 \t\n\r)。

預防最佳實踐

  1. 不要直接複製網頁/文件中的代碼片段——先貼到純文字編輯器(Notepad++, VS Code, Sublime)再複製到 IDE。
  2. 啟用 IDE 的「檢查隱形字元」檢查項(IntelliJ: Editor → Inspections → General → Non-ASCII characters)。
  3. 路徑字串優先用 NIO.2 Paths.get 或 FileSystems.getDefault().getPath(),避免手工拼接分隔符。
  4. 單元測試覆蓋檔案路徑構建邏輯,包含含空格、中文、特殊字元的路徑。

補充:答案提到的「盤符小寫」是誤導

Windows 路徑**不分大小寫**,D:\ 與 d:\ 等價。真正修好的原因是重新輸入時去除了隱形字元,而非大小寫變化。

總結: FileNotFoundException 伴隨「語法不正確」且路徑看似正確時,**優先懷疑字串含隱形 Unicode 控制字元**。用十六進位檢視、IDE 顯示空白字元、手動重打路徑三步驟可快速定位解決。

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