引數中的空格和其他特殊字元

首先,在引數中處理空格的問題實際上並不是 Java 問題。相反,它是一個需要由執行 Java 程式時使用的命令 shell 處理的問題。

作為一個例子,讓我們假設我們有以下簡單的程式來列印檔案的大小:

import java.io.File;

public class PrintFileSizes {
    
    public static void main(String[] args) {
        for (String name: args) {
            File file = new File(name);
            System.out.println("Size of '" + file + "' is " + file.size());
        }
    }
}

現在假設我們想要列印路徑名中包含空格的檔案的大小; 例如/home/steve/Test File.txt。如果我們執行這樣的命令:

$ java PrintFileSizes /home/steve/Test File.txt

shell 不會知道/home/steve/Test File.txt 實際上是一個路徑名。相反,它將向 Java 應用程式傳遞 2 個不同的引數,這些引數將嘗試查詢各自的檔案大小,並且因為具有這些路徑(可能)的檔案不存在而失敗。

使用 POSIX shell 的解決方案

POSIX 外殼包括 sh 以及 bashksh 等衍生物。如果你正在使用其中一個 shell,那麼你可以通過引用引數來解決問題。

$ java PrintFileSizes "/home/steve/Test File.txt"

路徑名周圍的雙引號告訴 shell 它應該作為單個引數傳遞。發生這種情況時,將刪除引號。還有其他幾種方法可以做到這一點:

$ java PrintFileSizes '/home/steve/Test File.txt'

單(直)引號被視為雙引號,除了它們還抑制引數內的各種擴充套件。

$ java PrintFileSizes /home/steve/Test\ File.txt

反斜槓會轉義以下空格,並使其不被解釋為引數分隔符。

為了更全面的文件,包括如何在引數處理其他特殊字元的描述,請參閱引用主題的 Bash文件。

Windows 解決方案

Windows 的基本問題是在作業系統級別,引數作為單個字串( ) 傳遞給子程序。這意味著解析(或重新解析)命令列的最終責任落在程式或其執行時庫上。有很多不一致的地方。

在 Java 案例中,簡要說一下:

  • 你可以在 java 命令中的引數周圍放置雙引號,這樣就可以傳遞帶有空格的引數。

  • 顯然,java 命令本身正在解析命令字串,它或多或少地得到它

  • 但是,當你嘗試將此與在批處理檔案中使用 SET 和變數替換相結合時,是否會刪除雙引號會變得非常複雜。

  • cmd.exe 殼顯然有其他逃逸機制; 例如,加倍雙引號,並使用^轉義。

有關更多詳細資訊,請參閱批處理檔案文件。