Tôi đang cố tạo ứng dụng giao diện người dùng trong Java để xử lý các chuyển đổi SVG hàng loạt bằng tính năng dòng lệnh của Inkscape. Tôi đang lấy và cập nhật mã từ https://sourceforge.net/projects/conversionsvg/. Cách nhà phát triển ban đầu xử lý gọi Inkscape theo Runtime.getRuntime(). Exec (Chuỗi). Vấn đề tôi đang gặp phải là một số mâu thuẫn giữa việc sử dụng methodA và methodB. Tôi đã tạo một dự án thử nghiệm java đơn giản để chứng minh các hành động khác nhau đang được thực hiện.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();
}
}
quả
Cả methodA (String) cuộc gọi làm việc, nhưng khi methodB (String []) được gọi là Inkscape đã được bắt đầu và các đối số được truyền không chính xác. Sau methodB (String []) thực hiện tôi nhận được một hộp thoại báo lỗi Inkscape cho từng nói
Không tải được các yêu cầu tập tin -f C: /test.svg -D -w 100 -h 100 -e C : \ RuntimeExec-methodB.png
Không tải được các yêu cầu tập tin -f C: /test.svg -D -w 100 -h 100 -e C: \ ProcessBuilder-methodB.png
và khi tôi nhấp vào Đóng trên hộp thoại, Inkscape bật lên với một tài liệu trống mới. Vì vậy, tôi đoán tôi có một vài câu hỏi:
Sự khác nhau giữa Runtime.getRuntime(). Exec (String) và Runtime.getRuntime(). Exec (String [])?
javadoc nói rằng Runtime.exec (String) cuộc gọi Runtime.exec (lệnh, null) (đó là Runtime.exec (cmd String, String [] envp)) mà trong lần lượt gọi Runtime.exec (cmdarray, envp) (là Runtime.exec (String [] cmdarray, String [] envp)). Vì vậy, nếu Runtime.getRuntime(). Exec (String) đang gọi Runtime.exec (String []) anyways, tại sao tôi nhận được kết quả khác nhau khi sử dụng các phương pháp khác nhau?
Có phải điều gì đó đang xảy ra ở hậu trường nơi Java thiết lập môi trường khác nhau tùy thuộc vào phương pháp nào được gọi?
Tôi khá chắc chắn rằng Java xử lý tách các đối số trong cả hai 'ProcessBuilder' hoặc' Runtime.exec() ', nhưng nếu không chính xác. – Jonathan
@ Jonathan, xem nhanh Thời gian chạy cho thấy bạn đúng - StringTokenizer được sử dụng để chia nhỏ chuỗi trên khoảng trắng. Điều đó có nghĩa là nếu bạn có khoảng trống trong đường dẫn của tệp thi hành, bạn sẽ cần sử dụng Runtime.exec (String []). – userkci