参数中的空格和其他特殊字符
首先,在参数中处理空格的问题实际上并不是 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
壳显然有其他逃逸机制; 例如,加倍双引号,并使用^
转义。
有关更多详细信息,请参阅批处理文件文档。