ProcessBuilder vs Runtime.exec ()
Estou tentando criar um aplicativo de front-end em Java para manipular conversões em lote de SVG usando o recurso de linha de comando do Inkscape. Estou recebendo e atualizando o código dehttps://sourceforge.net/projects/conversionsvg/. A maneira como o desenvolvedor original lidou com o InkscapeRuntime.getRuntime (). Exec (String). O problema que estou enfrentando é algumas inconsistências entre o uso de methodA e methodB. Criei um projeto de teste java simples para demonstrar as diferentes ações que estão sendo executadas.
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();
}
}
Resultado
AmbosmethodA (String) chama de trabalho, mas quandomethodB (String []) é chamado Inkscape está sendo iniciado e os argumentos estão sendo transmitidos incorretamente. Depois demethodB (String []) executa, recebo uma caixa de diálogo de erro do Inkscape para cada ditado
Falha ao carregar o arquivo solicitado -f C: /test.svg -D -w 100 -h 100 -e C: \ RuntimeExec-methodB.png
Falha ao carregar o arquivo solicitado -f C: /test.svg -D -w 100 -h 100 -e C: \ ProcessBuilder-methodB.png
e quando clico em Fechar na caixa de diálogo, o Inkscape aparece com um novo documento em branco. Então, acho que tenho algumas perguntas:
Qual é a diferença entre Runtime.getRuntime (). Exec (String) e Runtime.getRuntime (). Exec (String [])?
JavaDoc diz queRuntime.exec (String) chamadasRuntime.exec (comando, nulo) (qual éRuntime.exec (String cmd, String [] envp)) que por sua vez chamaRuntime.exec (cmdarray, envp) (qual éRuntime.exec (String [] cmdarray, String [] envp)) Então seRuntime.getRuntime (). Exec (String) está chamandoRuntime.exec (String []) Enfim, por que estou obtendo resultados diferentes ao usar métodos diferentes?
Há algo acontecendo nos bastidores em que o Java configura o ambiente de maneira diferente, dependendo de qual método é chamado?