3

次のタスクであなたの提案とガイダンスが必要です。私は、ECC200データマトリックスバーコードの画像ファイルを読み取り、その内容を読み取り、デコードされたメッセージを標準出力に書き込むコマンドラインユーティリティに付属するlibdmtxを使用しています。LinuxプラットフォームのJavaプログラムでこのコマンドラインユーティリティを使用したいと思います。私はubuntulinuxを使用しています。Linuxマシンにlibdmtxをインストールしました。コマンドを呼び出すと

dmtxread -n /home/admin/ab.tif

Linuxターミナルでは、画像内のバーコードのデコードされた値をすぐに提供します。

Javaプログラムを使用してこのコマンドを呼び出すと、コマンドの実行時にコードstuksが実行され、dotnが出力を返します。プログラムが処理中であるか、ハングしているようです。

以下は、次のコマンドを呼び出す私のJavaコードです

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;


public class Classtest {

    public static void getCodes(){

        try 
        { 
            Process p; 
            String command[]=new String[3];
            command[0]="dmtxread";
            command[1]="-n";
            command[2]="/home/admin/ab.tif";

            System.out.println("Command : "+command[0]+command[1]+command[2]);
            p=Runtime.getRuntime().exec(command);  //I think hangs over here.

            BufferedReader reader=new BufferedReader(new InputStreamReader(p.getErrorStream()));
            String line=reader.readLine();
            if(line==null){
                reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
                line=reader.readLine();
                System.out.print("Decoded      :- "+line);
            }else{
                System.out.print("Error      :- "+line);
            }
            System.out.println(p.waitFor());

        }catch(IOException e1) {
            e1.getMessage();
            e1.printStackTrace();
        }catch(InterruptedException e2) {
            e2.getMessage();
            e2.printStackTrace();
        } 


    }
    public static void main(String args[]){
        getCodes();
    }

}

私のコードがどこで間違っているのか友達に教えてください。

私は次の記事を参照しましたが、助けを得ることができません

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1

友達を案内してください!ありがとうございました!

これは、ProcessBuilderクラスを使用した新しいコードです。このコードも上記のコードと同じ出力を提供します。つまり、Process process = pb.start();の行でハングします。

public class Test {

public static void main(final String[] args) throws IOException, InterruptedException {
    //Build command 
    List<String> commands = new ArrayList<String>();
    commands.add("dmtxread");
    commands.add("-n");
    commands.add("/home/admin/ab.tif");
    System.out.println(commands);

    //Run macro on target
    ProcessBuilder pb = new ProcessBuilder(commands);
    pb.redirectErrorStream(true);
    Process process = pb.start();

    //Read output
    StringBuilder out = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line = null, previous = null;
    while ((line = br.readLine()) != null){
        System.out.println(line);
    }

    //Check result
    if (process.waitFor() == 0)
        System.out.println("Success!");
    System.exit(0);

    //Abnormal termination: Log command parameters and output and throw        ExecutionException
    System.err.println(commands);
    System.err.println(out.toString());
    System.exit(1);
}

}

この問題を解決するために私を導いてください。ありがとうございます!

4

3 に答える 3

4

readLine は、エラー ストリームから新しい行を受信するまでブロックします。したがって、出力がない場合、プログラムは最初の readLine を通過しません。

簡単にするために、 のProcessBuilder代わりにa を使用することをお勧めしますRuntime.exec()。これにより、次のように 2 つの InputStream をマージできます。

ProcessBuilder builder = new ProcessBuilder(cmd,arg0,arg1);
builder.redirectErrorStream(true);
Process process = builder.start();

これで、1 つから読み取ることができます。

別の方法として、別々のスレッドを使用して 2 つの InputStream を使用することもできます。

それが役立つことを願っています

于 2012-05-09T11:47:31.957 に答える
2

あなたのストリーム消費コードは非常に混乱しています。stderr から 1 行を読み取ろうとして、そのリーダーを放棄してから、stdout から 1 行を読み取ろうとします。

  1. プログラムが stderr に何も出力しない場合は、2 行目でハングアップします。
  2. プログラムが stderr に送信するものが多すぎてバッファがいっぱいになると、プログラム自体がブロックされ、Java が でブロックされwaitForます。
  3. これらはどちらも stdout に適用されます。

プロセスの出力ストリームを消費する適切な方法は、リンクした記事で詳しく説明されています。そのアドバイスを受け取ってください。誰もあなたにそれ以上のアドバイスを与えることはできません.

于 2012-05-09T11:42:08.577 に答える
0

プログラムで何が正確に発生し、どこでハングするかはわかりません(デバッガーまたはトレース出力を使用して確認できます)が、考えられるシナリオは次のとおりです。

プログラムが2行のテキストを出力したいとします。または1行だけですがstderrに。コードはstdoutから1行だけを読み取り、プロセスが終了するのを待ちます。これは、子プログラムがリーダーが次の行を読み取るのを待つ可能性があることを意味します。そのため、write誰かがパイプのブロックを解除するまで、永久に待機します。

コマンドラインから実行する場合dmtxread、出力パイプでブロッキングが発生しないため、プログラムは正常に実行されます。

于 2012-05-09T11:37:29.543 に答える