Java Language Espaces et autres caractères spéciaux dans les arguments


Exemple

Tout d'abord, le problème de la gestion des espaces dans les arguments n'est PAS un problème Java. Il s'agit plutôt d'un problème qui doit être traité par le shell de commandes que vous utilisez lorsque vous exécutez un programme Java.

À titre d'exemple, supposons que nous ayons le programme simple suivant qui imprime la taille d'un fichier:

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());
        }
    }
}

Maintenant, supposons que nous voulions imprimer la taille d'un fichier dont le chemin contient des espaces; par exemple /home/steve/Test File.txt . Si nous exécutons la commande comme ceci:

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

le shell ne saura pas que /home/steve/Test File.txt est en fait un chemin d'accès. Au lieu de cela, il transmettra 2 arguments distincts à l'application Java, qui tentera de trouver leur taille de fichier respective, et échouera car les fichiers avec ces chemins (probablement) n'existent pas.

Solutions utilisant un shell POSIX

Coquilles comprennent POSIX sh sous forme de dérivés bien tels que bash et ksh . Si vous utilisez l'un de ces shells, vous pouvez résoudre le problème en citant l'argument.

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

Les guillemets autour du nom de chemin indiquent au shell qu'il doit être transmis en un seul argument. Les citations seront supprimées lorsque cela se produira. Il y a plusieurs autres façons de le faire:

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

Les guillemets simples (droits) sont traités comme des guillemets, sauf qu'ils suppriment également diverses extensions dans l'argument.

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

Une barre oblique inverse échappe à l'espace suivant et l'empêche d'être interprétée comme un séparateur d'arguments.

Pour une documentation plus complète, y compris des descriptions sur la manière de traiter d'autres caractères spéciaux dans les arguments, veuillez vous reporter à la rubrique de citation dans la documentation de Bash .

Solution pour Windows

Le problème fondamental de Windows est qu'au niveau du système d'exploitation, les arguments sont transmis à un processus enfant sous la forme d'une chaîne unique ( source ). Cela signifie que la responsabilité ultime de l'analyse (ou de la nouvelle analyse) de la ligne de commande incombe au programme ou à ses bibliothèques d'exécution. Il y a beaucoup d'incohérence.

Dans le cas de Java, pour faire court:

  • Vous pouvez placer des guillemets doubles autour d'un argument dans une commande java , ce qui vous permettra de transmettre des arguments avec des espaces.

  • Apparemment, la commande java elle-même analyse la chaîne de commande

  • Cependant, lorsque vous essayez de combiner cela avec l'utilisation de SET et de la substitution de variables dans un fichier de commandes, il devient vraiment compliqué de savoir si les guillemets doubles sont supprimés.

  • Le shell cmd.exe a apparemment d'autres mécanismes d'échappement; par exemple, doubler les guillemets doubles et utiliser ^ échappent.

Pour plus de détails, reportez-vous à la documentation de Batch-File .