2010-10-22 17 views
9

Inkscape'in komut satırı özelliğini kullanarak toplu SVG dönüşümlerini işlemek için Java'da bir önyüz uygulaması oluşturmaya çalışıyorum. Kodu alıyorum ve https://sourceforge.net/projects/conversionsvg/'dan güncelliyorum. Orijinal geliştiricinin Inkscape'i Runtime.getRuntime(). Exec (String) numaralı çağrıyla işleme biçimi. Çalıştığım sorun, methodA ve methodB kullanımı arasında bazı tutarsızlıklar. Gerçekleştirilen farklı eylemleri göstermek için basit bir java testi projesi oluşturdum.ProcessBuilder ve 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(); 
    } 
} 

Sonuç

Hem Yöntemia (String) aramalar çalışır, ancak Yöntemib (String []) çağrıldığında Inkscape ait olan ve bağımsız değişkenler, yanlış geçirilir edilmektedir. Yöntemib (String []) yürütür sonra her

söyleyen bir Inkscape hata iletişim kutusu

İstenen dosya f C yüklenemedi: /test.svg -D -w 100-h 100 -e Cı : \ RuntimeExec-methodB.png

istenen dosya f C yüklenemedi: /test.svg -D -w 100-h 100 -e C: \ ProcessBuilder-methodB.png

ve İletişim kutusundaki Kapat'ı tıkladığımda, Inkscape yeni bir boş belge ile açılır. Yani, sanırım birkaç sorum var:

Runtime.getRuntime(). Exec (String) ve Runtime.getRuntime(). Exec (String []) arasındaki fark nedir?

javadoc diyor Runtime.exec (String) aramalar Runtime.exec (boş komutu) (Runtime.exec (String cmd olan String [] envp)) ki burada aramaları Runtime.exec (cmdarray, envp) (hangisi Runtime.exec (Dize [] cmdarray, String [] envp)). Yani, Runtime.getRuntime(). Exec (String)Runtime.exec (String [])'u çağırıyorsa, neden farklı yöntemler kullanırken farklı sonuçlar alıyorum?

Java'nın hangi yöntemi çağırdığına bağlı olarak ortamı farklı kılan sahnelerin arkasında bir şey mi oluyor?

cevap

12

Sorununuzun, argüman listenizi belirttiğiniz yoldan kaynaklandığından şüpheleniyorum. Esasen, Inkscape'e "-f C:/test.svg -D -w 100 -h 100 -e C:\RuntimeExec-methodB.png" tek bir argüman olarak geçiyorsunuz.

bunu gibi bireysel değişkenler geçirebilirsiniz yapmanız gerekenler:

Eğer Runtime.exec(String) kullandığınızda Kabaca, sen geçmek değeri kabuk tarafından değerlendirilir alır konuşan
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"}; 

, dışarı ayrıştırır hangi argüman listesi. Runtime.exec(String[])'u kullandığınızda, argüman listesini veriyorsunuz, bu yüzden işleme gerekmiyor. Bunu yapmanın bir yararı, argümanların kendisi tarafından değerlendirilmeyeceği için, kabuğa özel değerlerden kaçmak zorunda kalmamanızdır.

+0

Java'nın argümanları 'ProcessBuilder' veya 'Runtime.exec() 'olarak bölme işlemlerini gerçekleştirdiğinden eminim, ancak aksi durumda düzeltildi. – Jonathan

+2

@Jonathan, Runtime hızlı bir bakış size doğru olduğunu gösterir - StringTokenizer, boşlukta dizgeyi ayırmak için kullanılır. Bu, yürütülebilir dosyanızın yolunda boşluk varsa, Runtime.exec (String []) kullanmanız gerekecektir. – userkci

İlgili konular