Java Language Spaces and other special characters in arguments


First of all, the problem of handling spaces in arguments is NOT actually a Java problem. Rather it is a problem that needs to be handled by the command shell that you are using when you run a Java program.

As an example, let us suppose that we have the following simple program that prints the size of a 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());

Now suppose that we want print the size of a file whose pathname has spaces in it; e.g. /home/steve/Test File.txt. If we run the command like this:

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

the shell won't know that /home/steve/Test File.txt is actually one pathname. Instead, it will pass 2 distinct arguments to the Java application, which will attempt to find their respective file sizes, and fail because files with those paths (probably) do not exist.

Solutions using a POSIX shell

POSIX shells include sh as well derivatives such as bash and ksh. If you are using one of these shells, then you can solve the problem by quoting the argument.

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

The double-quotes around the pathname tell the shell that it should be passed as a single argument. The quotes will be removed when this happens. There are a couple of other ways to do this:

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

Single (straight) quotes are treated like double-quotes except that they also suppress various expansions within the argument.

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

A backslash escapes the following space, and causes it not to be interpreted as an argument separator.

For more comprehensive documentation, including descriptions of how to deal with other special characters in arguments, please refer to the quoting topic in the Bash documentation.

Solution for Windows

The fundamental problem for Windows is that at the OS level, the arguments are passed to a child process as a single string (source). This means that the ultimate responsibility of parsing (or re-parsing) the command line falls on either program or its runtime libraries. There is lots of inconsistency.

In the Java case, to cut a long story short:

  • You can put double-quotes around an argument in a java command, and that will allow you to pass arguments with spaces in them.

  • Apparently, the java command itself is parsing the command string, and it gets it more or less right

  • However, when you try to combine this with the use of SET and variable substitution in a batch file, it gets really complicated as to whether double-quotes get removed.

  • The cmd.exe shell apparently has other escaping mechanisms; e.g. doubling double-quotes, and using ^ escapes.

For more detail, please refer to the Batch-File documentation.