2012-11-20 31 views
7

私はRuntime.getRuntime().exec()メソッドを使ってコマンドラインを使ってプログラム "tesseract"のインスタンスを実行するJavaプログラムを作成しようとしていました。java getRuntime()。exec()を使って引数を持つコマンドラインプログラムを実行するには?

背景Tesseractは、画像にOCR(Optical Character Recognition)を実行するために使用される無料のオープンソースプログラムです。画像ファイルを取り込んでテキスト文書を出力します。 、最初の引数がたTesseractプログラムを呼び出す

tesseract "C:\Program Files (x86)\Tesseract-OCR\doc\eurotext.tif" "C:\Users\Dreadnought\Documents\TestingFolder\out" 

:それは

tesseract imageFilePath outFilePath [optional arguments] 

(コマンドプロンプトシェル内から)を実行するには、このコマンドを使用する例コマンドラインプログラムでありますsecondは画像ファイルへの絶対パスで、最後の引数は出力ファイルのパスと名前です。 Tesseractには、拡張子を必要としない出力ファイルの名前だけが必要です。

コマンドプロンプトから作業すると完璧に動作します。しかし、私はこれをJavaプログラムから実行したいと思っていて、いくつかのエラーが発生していました。

それはdirコマンドの結果をプリントアウトオフ開始点

public class Main 
{ 
    public static void main(String args[]) 
    { 
     try 
     { 
     Runtime rt = Runtime.getRuntime(); 
     String cmdString = "cmd /c dir"; 

     System.out.println(cmdString); 
     Process pr = rt.exec(cmdString); 

     BufferedReader input = new BufferedReader(new InputStreamReader(
                pr.getInputStream())); 

     String line = null; 

     while ((line = input.readLine()) != null) 
     { 
      System.out.println(line); 
     } 

     int exitVal = pr.waitFor(); 
     System.out.println("Exited with error code " + exitVal); 

     } 
     catch (Exception e) 
     { 
     System.out.println(e.toString()); 
     e.printStackTrace(); 
     } 
    } 
} 

として非常に有用であることが、このコードこれを発見しました。しかし、私のようにそれを修正したとき

public class Main 
{ 
    public static void main(String args[]) 
    { 
     try 
     { 
     Runtime rt = Runtime.getRuntime(); 
     String imageFilePath = "\"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\""; 
     String outputFilePath = "\"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\""; 
     String[] commands = {"cmd", "/c", "tesseract", imageFilePath, outputFilePath }; 

     Process pr = rt.exec(commands); 

     BufferedReader input = new BufferedReader(new InputStreamReader(
       pr.getInputStream())); 

     String line = null; 

     while ((line = input.readLine()) != null) 
     { 
      System.out.println(line); 
     } 

     int exitVal = pr.waitFor(); 
     System.out.println("Exited with error code " + exitVal); 
     } 
     catch (Exception e) 
     { 
     System.out.println(e.toString()); 
     e.printStackTrace(); 
     } 
    } 
} 

出力するものはExited with error code 1です。これは、プロセスがエラーで終了した場合に期待される出力です。

私はさらに"cmd /c tesseract \"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\" \"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\""を渡そうとしましたが、同じエラーが発生しました。

Using Quotes within getRuntime().execによれば、私は引用符をエスケープしようとしていたので、私は文字列配列を渡したのです。しかし、私はまだExited with error code 1を取得しています。

java Runtime.getRuntime().exec()コマンドでコマンドラインプログラムを実行することはできますか?


EDIT:問題はまだ私はEvgeniy DorofeevとNandkumar Tekaleは、以下の提案と推論の同じラインに沿って考えて "CMD/C" を使用していない試してみました

が発生しています。しかし、私は異なる種類のエラーが発生します:

java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system cannot find the file specified 
java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system cannot find the file specified 
    at java.lang.ProcessBuilder.start(Unknown Source) 
    at java.lang.Runtime.exec(Unknown Source) 
    at java.lang.Runtime.exec(Unknown Source) 
    at Main.main(Main.java:15) 
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified 
    at java.lang.ProcessImpl.create(Native Method) 
    at java.lang.ProcessImpl.<init>(Unknown Source) 
    at java.lang.ProcessImpl.start(Unknown Source) 
... 4 more 

これはもっと情報を与えますか?私は本当にこの問題を引き起こしているのか不思議です。また、私の引数にエスケープされた引用を追加するかどうかにかかわらず、同じ問題があります。


EDIT 2:気まぐれで私はたTesseract実行ファイルの絶対パスを提供し、cmd /cを使用していない魔法のように働きました。私は質問がRuntime.getRuntime().exec()環境変数を呼び出すことができないと思いますか?

+0

私はわかりませんが、問題は、 'で存在する可能性がありますパスにスペースを含むC:\\ Program Files(x86) ' –

+0

私はこれが問題の根本だと考えていたので、引用符を使用しようとしたのですが、エグゼクティブと一緒にrk、私はこの仕事をするかもしれない方法についての提案がありますか? – Samuel

+0

配列を 'rt.exec()'に渡しています。あなたの議論の始めと終わりに引用符を入れないでください。これは、引数を分割する方法に関するシェルの情報ですが、すでに行っています。 –

答えて

1

ウェルtesseractは外部コマンドなので、cmdと一緒に使用する必要はありません。環境変数にtesseractを追加してください。

String[] commands = {"tesseract", imageFilePath, outputFilePath }; 

存在ステータス1は、間違った機能を意味します。 process exit status

+0

tesseractは既に環境変数に入っています。 – Samuel

+0

あなたはそれをcmd promptで直接実行して確認しましたか? –

+0

はい、コマンドプロンプトからうまく動作します – Samuel

0

たとえば、C:\Program Filesなどの古いDOSスタイルのパスを使用して再コンパイルして展開する必要がない別の回避策は、C:\Progra~1となります。もちろん、これは設定ファイルやDBやレジストリなどからパスを読み込んでいる場合にのみ役立ちます。

0

別の回避策は、/usr/local/Cellar/tesseract/3.02.02/のようなファイルの完全なインストールパスを与えることです。ビン/たTesseract」

0

あなたは、エラーが発生したときので、あなたは(あなたがキャプチャしている)STDOUTからそれらを受けていない、STDERRをキャプチャしていないしてみてください。

BufferedReader input = new BufferedReader(new InputStreamReader(
       pr.getErrorStream())); 
関連する問題