我想在Java中創建一個前端應用程序來處理批量SVG轉換使用Inkscape的命令行功能。我正在更新https://sourceforge.net/projects/conversionsvg/的代碼。原始開發者通過Runtime.getRuntime()。exec(String)處理調用Inkscape的方式。我遇到的問題是使用methodA和methodB之間的一些不一致。我創建了一個簡單的java測試項目來演示正在執行的不同操作。ProcessBuilder vs Runtime.exec()
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();
}
}
結果
兩個了methodA(字符串)呼叫無效,但是當的methodB(字符串[])被稱爲正在啓動Inkscape中和參數被錯誤地傳遞。 的methodB(字符串[])執行後,我得到一個Inkscape的錯誤對話框對每個說法
無法加載請求的文件-f C:/test.svg -D -w 100 -h 100 -eÇ :\ RuntimeExec-methodB.png
無法加載所請求的文件-f C:/test.svg -D -w 100 -h 100 -e C:\的ProcessBuilder-methodB.png
和當我點擊對話框上的關閉時,Inkscape彈出一個新的空白文檔。所以,我想我有幾個問題:
Runtime.getRuntime()。exec(String)和Runtime.getRuntime()。exec(String [])有什麼區別?
JavaDoc的說,的Runtime.exec(字符串)呼叫的Runtime.exec(命令,NULL)(其爲的Runtime.exec(字符串CMD,字符串[] envp)),其在打電話Runtime.exec(cmdarray,envp)(即Runtime.exec(String [] cmdarray,String [] envp))。因此,如果Runtime.getRuntime().exec(String)正在調用Runtime.exec(String [])反正,爲什麼我在使用不同的方法時得到不同的結果?
發生在幕後的事情是Java根據調用的方法設置不同的環境嗎?
我很確定Java處理分裂'ProcessBuilder'或'Runtime.exec()'中的參數,但在其他方面是正確的。 – Jonathan 2010-10-22 14:16:11
@Jonathan,快速瀏覽一下Runtime表明你是正確的--StringTokenizer用來分割空白字符串。這意味着如果您的可執行文件路徑中有空格,則需要使用Runtime.exec(String [])。 – userkci 2010-10-22 15:28:22