引數中的空格和其他特殊字元
首先,在引數中處理空格的問題實際上並不是 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
以及 bash
和 ksh
等衍生物。如果你正在使用其中一個 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
殼顯然有其他逃逸機制; 例如,加倍雙引號,並使用^
轉義。
有關更多詳細資訊,請參閱批處理檔案文件。