0

私は糸脱毛の世界ではかなり新しい人で、この問題を1週間解決しようとしています。

Threadクラスのrunメソッドが何らかの理由で呼び出されていません。理由はわかりません(ただし、知りたいです)。

        ProcessBuilder processBuilder = new ProcessBuilder();

        processBuilder.command("/bin/sh", "-c", "echo \"w30000001z,none,16488,,181075\nw30000001z,none,16488,,181082\n\" | /home/beehive/bin/exec/tableSize");
        Process process = processBuilder.start();
        process.waitFor(); 

        InputStream stdin = process.getInputStream();
        OutputStream stdout = process.getOutputStream();
        InputStream stderr = process.getErrorStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));
        BufferedReader error = new BufferedReader(new InputStreamReader(stderr));
        StreamGobbler errorStream = new StreamGobbler(process.getErrorStream(), "ERROR");
        StreamGobbler outputStream = new StreamGobbler(process.getInputStream(), "OUTPUT");

        errorStream.start();
        outputStream.start();
        errorStream.join();
        outputStream.join();

tableSizeは、stdinを介して入力を受け取り、それを処理して数行のテキストを出力するPython実行可能ファイルです。この出力を収集して、さらに処理する必要があります。

inputStreamとerrorStreamの出力を処理するための別個のスレッドがあります。このスレッドクラスは以下のとおりです。

/* StreamGobbler.java */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

class StreamGobbler extends Thread
{
    InputStream is;
    String type;
    OutputStream os;

    StreamGobbler(InputStream is, String type)
    {
        this(is, type, null);

    }
    StreamGobbler(InputStream is, String type, OutputStream redirect)
    {
        this.is = is;
        this.type = type;
        this.os = redirect;
    }

    public void run()
    {
        try
        {
            PrintWriter pw = null;
            if (os != null)
                pw = new PrintWriter(os);

            System.out.println("Ajay" + type);
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
            {
                if (pw != null)
                    pw.println(line);
                System.out.println(type + ">" + line);    
            }
            if (pw != null)
                pw.flush();
        } catch (IOException ioe)
            {
            ioe.printStackTrace();  
            }
    }
}

何らかの理由で、StreamGobblerクラスのrunメソッドが呼び出されていません。ただし、このクラスのコンストラクターは実行されています。

どんな助けでも大歓迎です。

4

3 に答える 3

9

を呼び出す前に、ストリーム ゴブラーを開始する必要がありますprocess.waitFor()

ストリーム ゴブラーは、外部プロセスが書き込み中にブロックされないように、外部プロセスの出力/エラー ストリームを読み取って破棄します。しかし、あなたのやり方では、出力を飲み込もうとする前に、プロセスは書き込みを終了する (そして終了する) 必要があります。

結果 - デッドロック ... 外部プロセスが出力ストリームに書き込みすぎた場合。


実際、主な問題は、Java コードが に何も書き込まないことだと思いますinputStream。したがって、外部プロセスはそこに座って、決して到着しない入力を待っています...そしてprocess.waitFor()外部プロセスを待ちます。デッドロック。

物事の正しい順序は次のとおりです。

  1. プロセスをビルドして開始します。
  2. ゴブラーを構築して起動します。
  3. 入力ストリームを開きます。
  4. 入力ストリームに書き込みます。
  5. 入力ストリームを閉じます。
  6. process.waitFor()プロセスの戻りコードを呼び出して確認します。
  7. ゴブラーによってキャプチャされた出力を見てください
于 2011-03-28T10:02:05.483 に答える
1

の前にSTDOUTおよび/またはSTDERRを使用する必要があります。Process.waitFor()これは優れた記事です: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=2

于 2011-03-28T10:20:41.313 に答える
1

1) 必要ない場合は、waitFor() を削除してみてください。プロセスの実行が完了するまで、実行中のスレッドを待機させるだけです。

于 2011-03-28T10:22:09.477 に答える