9

Inkscapeのコマンドライン機能を使用してバッチSVG変換を処理するフロントエンドアプリをJavaで作成しようとしています。https://sourceforge.net/projects/conversionsvg/からコードを取得して更新しています。元の開発者がRuntime.getRuntime()。exec(String)によるInkscapeの呼び出しを処理した方法。私が遭遇している問題は、methodAとmethodBの使用の間のいくつかの矛盾です。実行されているさまざまなアクションを示すために、単純なJavaテストプロジェクトを作成しました。

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(String)呼び出しは両方とも機能しますが、methodB (String [])が呼び出されると、Inkscapeが開始され、引数が正しく渡されません。methodB(String [])を実行した後、各発言に対してInkscapeエラーダイアログが表示されます

要求されたファイルのロードに失敗しました-fC:/test.svg -D -w 100 -h 100 -e C:\ RuntimeExec-methodB.png

要求されたファイルのロードに失敗しました-fC:/test.svg -D -w 100 -h 100 -e C:\ ProcessBuilder-methodB.png

ダイアログで[閉じる]をクリックすると、Inkscapeがポップアップして新しい空白のドキュメントが表示されます。だから、私はいくつかの質問があると思います:

Runtime.getRuntime()。exec(String)とRuntime.getRuntime()。exec(String [])の違いは何ですか?

JavaDocによると、Runtime.exec(String)Runtime.exec(command、null)Runtime.exec(String cmd、String [] envp))を呼び出し、Runtime.exec(cmdarray、envp)Runtime )を呼び出します。 .exec(String [] cmdarray、String [] envp))。それで、Runtime.getRuntime()。exec(String)がRuntime.exec(String [])を呼び出している場合、異なるメソッドを使用すると、なぜ異なる結果が得られるのですか?

どのメソッドが呼び出されるかによって、Javaが環境を異なる方法でセットアップする舞台裏で何かが起こっていますか?

4

1 に答える 1

12

あなたの問題はあなたがあなたの引数リストを指定している方法に起因しているのではないかと思います。基本的に、Inkscapeへの単一の引数-f C:/test.svg -D -w 100 -h 100 -e C:\RuntimeExec-methodB.pngとして「」を渡します。

あなたがする必要があるのは、次のように、引数を個別に渡すことです。

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"};

大まかに言えば、を使用するRuntime.exec(String)と、渡した値はシェルによって評価され、シェルが引数リストを解析します。を使用Runtime.exec(String[])すると、引数リストが提供されるため、処理する必要はありません。これを行う利点は、引数がシェルによって評価されないため、シェルに固有の値をエスケープする必要がないことです。

于 2010-10-22T14:04:19.860 に答える