Question

Je suis en train de créer une application frontend en Java pour gérer les conversions SVG lots en utilisant la fonction de ligne de commande de Inkscape. Je vais prendre et mettre à jour le code de https://sourceforge.net/projects/conversionsvg/ . La façon dont le développeur original traité appelant Inkscape par Runtime.getRuntime (). Exec (String) . La question que je suis en cours d'exécution en est des incohérences entre l'utilisation methodA et methodB. J'ai créé un projet simple test java pour démontrer les différentes actions exécutées.

CallerTest.java

package conversion;

import java.io.IOException;

public class CallerTest {

    static String pathToInkscape = "\"C:\\Program Files\\Inkscape\\inkscape.exe\"";  

    public static void main(String[] args) {

      ProcessBuilderCaller processBuilder = new ProcessBuilderCaller();
      RuntimeExecCaller runtimeExec = new RuntimeExecCaller();

      // methodA() uses one long command line string
      try {

        String oneLongString_ProcessBuilder = pathToInkscape + " -f \"C:\\test.svg\" -D -w 100 -h 100 -e \"C:\\ProcessBuilder-methodB.png\"";
        String oneLongString_RuntimeExec =    pathToInkscape + " -f \"C:\\test.svg\" -D -w 100 -h 100 -e \"C:\\RuntimeExec-methodA.png\"";

//        processBuilder.methodA(oneLongString_ProcessBuilder);
        runtimeExec.methodA(oneLongString_RuntimeExec);

      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }

      // methodB() uses an array containing the command and the options to pass to the command
      try {

        String[] commandAndOptions_ProcessBuilder = {pathToInkscape, " -f \"C:/test.svg\" -D -w 100 -h 100 -e \"C:\\ProcessBuilder-methodB.png\""};
        String[] commandAndOptions_RuntimeExec =    {pathToInkscape, " -f \"C:/test.svg\" -D -w 100 -h 100 -e \"C:\\RuntimeExec-methodB.png\""};

        processBuilder.methodB(commandAndOptions_ProcessBuilder);
//        runtimeExec.methodB(commandAndOptions_RuntimeExec);

      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
}

RuntimeExecCaller.java

package conversion;

import java.io.IOException;

public class RuntimeExecCaller {
    Process process;

    // use one string
    public void methodA(String oneLongString) throws IOException {
      process = Runtime.getRuntime().exec(oneLongString);
    }

    // use the array
    public void methodB(String[] commandAndOptions) throws IOException {
      process = Runtime.getRuntime().exec(commandAndOptions);
    }
}

ProcessBuilderCaller.java

package conversion;

import java.io.IOException;

public class ProcessBuilderCaller {
    Process process;

    // use one string
    public void methodA(String oneLongString) throws IOException {
      process = new ProcessBuilder(oneLongString).start();
    }

    // use the array
    public void methodB(String[] commandAndOptions) throws IOException {
      process = new ProcessBuilder(commandAndOptions).start();
    }
}

Résultat

Les deux methodA (String) appelle le travail, mais quand methodB (String []) est appelé Inkscape est en cours de démarrage et les arguments sont transmis de manière incorrecte. Après methodB (String []) exécute je reçois un message d'erreur Inkscape pour chaque dire

  

Impossible de charger le fichier demandé -f C: /test.svg -D -w 100 -h 100 -e C: \ RuntimeExec-methodB.png

     

Impossible de charger le fichier demandé -f C: /test.svg -D -w 100 -h 100 -e C: \ ProcessBuilder-methodB.png

et quand je clique sur Fermer dans la boîte de dialogue, Inkscape apparaît avec un nouveau document vierge. Donc, je suppose que j'ai quelques questions:

Quelle est la différence entre Runtime.getRuntime (). Exec (String) et Runtime.getRuntime (). Exec (String [])?

JavaDoc dit que Runtime.exec (String) Appels Runtime.exec (commande, null) (qui est Runtime.exec (String cmd, String [] envp) ) qui appelle à son tour Runtime.exec (cmdarray, envp) (qui est Runtime.exec (String [] cmdarray, String [] envp) ). Donc, si Runtime.getRuntime (). Exec (String) appelle Runtime.exec (String []) de toute façon, pourquoi suis-je recevoir des résultats différents lors de l'utilisation de différentes méthodes?

Quelque chose se passe dans les coulisses où Java définit l'environnement différemment selon la méthode est appelée?

Était-ce utile?

La solution

Je soupçonne que votre problème vient de la façon dont vous spécifiez votre liste d'arguments. Essentiellement, vous passez "-f C:/test.svg -D -w 100 -h 100 -e C:\RuntimeExec-methodB.png" comme un seul argument à Inkscape.

Ce que vous devez faire est de passer les arguments individuellement , comme ceci:

String[] commandAndOptions_ProcessBuilder = {pathToInkscape, "-f", "C:\\est.svg", "-D", "-w", "100", "-h", "100", "-e", "C:\\ProcessBuilder-methodB.png"};
String[] commandAndOptions_RuntimeExec = {pathToInkscape, "-f", "C:\\test.svg", "-D", "-w", "100", "-h", "100", "-e","C:\\RuntimeExec-methodB.png"};

En gros, lorsque vous utilisez Runtime.exec(String), la valeur que vous passez par l'obtient évaluée coquille, qui analyse la liste des arguments. Lorsque vous utilisez Runtime.exec(String[]), vous fournissez la liste des arguments, il ne traitement pas besoin. Un avantage de le faire est que vous ne devez pas échapper à des valeurs particulières à la coquille, que les arguments ne seront pas évaluées par elle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top