0

Java で単純なコマンドラッパーを作成するだけです。これは構築関数です。

Process process;
Thread in;
Thread out; 

public CommandWrapper(Process process) {
    this.process = process;
    final InputStream inputStream = process.getInputStream();
    // final BufferedReader
    //final BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
    final byte[] buffer = new byte[1024];
    out = new Thread() {
        // String line;
        int lineNumber = 0;

        public void run() {
            try {
                while (true) {
                    int count = inputStream.read(buffer);
                    System.out.println(lineNumber + ":"
                            + new String(buffer, 0, count - 1));
                    // line=r.readLine();
                    // System.out.println(lineNumber+":"+line);
                    lineNumber++;
                }
            } catch (Exception e) {

            }
        }
    };
    final BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));
    final OutputStream outputStream = process.getOutputStream();
    in = new Thread() {
        String line;

        public void run() {
            try {
                //while (true) {
                    outputStream.write((reader.readLine() + "/n")
                            .getBytes());
                    outputStream.flush();
                //}
            } catch (Exception e) {

            }
        }
    };
}

public void startIn() {
    in.start();
}

これはそれが呼び出すときです:

public static void main(String[] args) {
    try {
        CommandWrapper command = new CommandWrapper(Runtime.getRuntime()
                .exec("wget www.google.com"));
        //command.startIn();
        command.startOut();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

ls -l やその他のローカル コマンダーなどの単純なコマンドを実行すると問題なく動作しますが、wget コマンドを実行すると何も出力されません。私はその理由を知っています。

4

1 に答える 1

1

あなたが示したコードとそれをどのように使用するかについてのあなたの説明から、最良の推測は、例外が発生し、黙ってそれを飲み込むことです. catchこれは、次のように -blockが空の場合に発生します。

catch (Exception e) {
}

たまたま、スレッドのrun()メソッドにそれがあります。out

黙って例外を飲み込むことは、非常に悪い習慣です。

これは絶対にやってはいけません!アプリケーションによって適切な解決策は異なりますが、コンソール アプリケーションを作成しているので、おそらく例外のスタック トレースを出力する必要があります。Java では、これは次のように行われe.printStackTrace()ます。

catch (Exception e) {
    e.printStackTrace();
}

別のオプション (この特定のケースでは適切ではない可能性があります) は、おそらく別の例外 (たとえば、アプリケーション用に特別に作成したもの) でラップした後に、例外を再スローすることです。

catch (Exception e) {
    throw e;
}
// or
catch (Exception e) {
    throw new MyOwnException(e);
}

これら 2 つのいずれか (スタック トレースの出力または再スロー) を実行すると、例外が見過ごされることがなくなります。

ただし、例外のないルールはありません ;)

catch-clauseを空にすることが適切な場合があります。一部の操作で例外がスローされる可能性があることがわかっていて、それが発生したときに処理を続行したい場合は、空のcatch-clause を使用することをお勧めします。ただし、これが充当されるケースは、(少なくとも) 次の条件に限定されます。

  1. 例外の特定のタイプを知っている必要があります。一般的な例外をキャッチする必要はありませ(つまり、予測できない何らかの理由でスローされる可能性があるためです。空の句を使用する場合は、常に特定の例外タイプ (など)をキャッチします。catch (Exception e)catchIOException

  2. 例外がスローされた理由を知る必要があります。発生元がわかっている例外のみを飲み込む必要があります。他の例外を飲み込むと、コードが期待どおりに動作せず、その理由を理解できない、この状況のようになります。飲み込まれた例外は、飲み込まれて隠されるため、デバッグが非常に困難です。

  3. 例外を気にしないことを知っておく必要があります。空のcatch-clauses を使用する理由は、主に (読み取り:のみ) 使用しているコードが何かを例外として扱う状況を処理するためです。この文脈での例外的とは、「実際には起きてはならないことであり、起きた場合、何かが深刻に間違っていること」を意味します。

catch空の-clauses が適切な場合の例
: ファイルの絶対パスを指定して、読み取り用にファイルを開く他の誰かのコードを使用しているとします。そのようなルーチンのほとんどは、ファイルが存在しない場合に例外をスローします。クライアント コード (つまり、「ファイルを開くルーチン」を呼び出すコード) の仕事は、ファイルを開こうとする前にファイルが存在することを確認することです。たとえば、プログラムを実行しているユーザーがファイルを読み取る権限を持っていない場合にも、例外がスローされます。

さて、なぜファイルが開けなかったのかはあまり気にしないかもしれませんが、それができなかった場合は、続行したいだけです。その場合、ファイルの読み取りに関連するすべての例外を飲み込みます (Java では、おそらくIOExceptionいくつかの選別)。すべての例外を飲み込むのではなく、ファイルを開くことに関連する例外のみを飲み込むことに注意してください。

于 2012-12-26T03:30:19.860 に答える