ProcessBuilder vs Runtime.exec()
Je suis en train de créer une interface d'application en Java pour gérer lot SVG conversions à l'aide d'Inkscape ligne de commande de fonction. Je suis prise et mise à jour du code de https://sourceforge.net/projects/conversionsvg/. La façon dont le développeur d'origine traitées appel Inkscape par de l'Exécution.getRuntime().exec(String). La question que je suis en cours d'exécution dans certaines incohérences entre l'utilisation de la methodA et methodB. J'ai créé un simple java projet de test pour démontrer les différentes actions en cours d'exécution.
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) des appels, mais quand methodB(String[]) est Inkscape est en cours de démarrage et les arguments sont transmis de façon incorrecte. Après methodB(String[]) exécute, je reçois un Inkscape boîte de dialogue d'erreur 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 crois que j'ai quelques questions:
Quelle est la différence entre l'Exécution.getRuntime().exec(String) et de l'Exécution.getRuntime().exec(String[])?
JavaDoc dit que de l'Exécution.exec(String) appels de l'Exécution.exec(commande, null) (qui est de l'Exécution.exec(String cmd, String[] envp)) qui à son tour appelle de l'Exécution.exec(cmdarray, envp) (qui est de l'Exécution.exec(String[] cmdarray, String[] envp)). Donc, si de l'Exécution.getRuntime().exec(String) appelle de l'Exécution.exec(String[]) de toute façon, pourquoi j'obtiens des résultats différents lors de l'utilisation de méthodes différentes?
Est quelque chose qui se passe derrière les scènes où Java définit l'environnement différemment selon lequel la méthode est appelée?
OriginalL'auteur blastthisinferno | 2010-10-22
Vous devez vous connecter pour publier un commentaire.
Je soupçonne que votre problème vient de la façon dont vous êtes en précisant votre liste d'arguments. Essentiellement, vous êtes de passage "
-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 suit:
Grosso modo, lorsque vous utilisez
Runtime.exec(String)
, la valeur que vous transmettez sont évalués par le shell, qui analyse la liste des arguments. Lorsque vous utilisezRuntime.exec(String[])
, vous êtes en fournissant la liste des arguments, de sorte qu'il n'a pas besoin de traitement. Un avantage de cela est que vous n'avez pas à échapper à des valeurs de spécial pour le shell, comme les arguments ne seront pas évaluées par elle.ProcessBuilder
ouRuntime.exec()
, mais sinon correct.un rapide coup d'oeil à l'Exécution montre que vous êtes correct - StringTokenizer est utilisé pour rompre la chaîne sur les espaces. Ce qui signifie que si vous avez de l'espace dans votre exécutable du chemin, vous aurez besoin d'utiliser de l'Exécution.exec(String[]).
OriginalL'auteur userkci