2

以下は、プロジェクトで使用するコード スニペットの一部です。

public String fetchFromStream()
{
    try
    {
        int charVal;
        StringBuffer sb = new StringBuffer();

        while((charVal = inputStream.read()) > 0) {
            sb.append((char)charVal);
        }
        return sb.toString();
    } catch (Exception e)
    {
        m_log.error("readUntil(..) : " + e.getMessage());
        return null;
    } finally {
        System.out.println("<<<<<<<<<<<<<<<<<<<<<< Called >>>>>>>>>>>>>>>>>>>>>>>>>>>");
    }
}

最初、while ループはかなりうまく機能し始めます。しかし、おそらく最後の文字がストリームから読み取られた後、-1 の戻り値を取得することを期待していました。しかし、これが私の問題の始まりです。finally ブロックが実行されなくても、コードはハングします。

実行時に実際に何が起こっているかを確認するために、Eclipse でこのコードをデバッグしていました。while ループ内にポインター (デバッグ) を設定し、Char 値が 1 つずつ入力される StringBuffer を常に監視していました。しかし、while ループ内の状態を確認しているときに、突然、デバッグ コントロールが失われ、コードがハングアップ状態になるポイントが発生します。例外もスローされません!!

ここで何が起きてるの ?

編集::

これが、InputStream を取得する方法です。基本的に、Telnet には Apache Commons Net を使用しています。

private TelnetClient getTelnetSession(String hostname, int port)
{
    TelnetClient tc = new TelnetClient();
    try
    {
        tc.connect(hostname, port != 0 ? port : 23);

                    //These are instance variables
        inputStream = tc.getInputStream();
        outputStream = new PrintStream(tc.getOutputStream());

        //More codes...

        return tc;
    } catch (SocketException se)
    {
        m_log.error("getTelnetSession(..) : " + se.getMessage());
        return null;
    } catch (IOException ioe)
    {
        m_log.error("getTelnetSession(..) : " + ioe.getMessage());
        return null;
    } catch (Exception e)
    {
        m_log.error("getTelnetSession(..) : " + e.getMessage());
        return null;
    }
}
4

3 に答える 3

5

JavaDocsを見てください:

入力ストリームからデータの次のバイトを読み取ります。値 byte は、0 から 255 の範囲の int として返されます。ストリームの終わりに達したために使用可能なバイトがない場合、値 -1 が返されます。このメソッドは、入力データが使用可能になるか、ストリームの終わりが検出されるか、例外がスローされるまでブロックされます。

簡単に言うと、ストリームが終了した場合 (ファイルの終わりなど)、read()すぐに -1 を返します。ただし、ストリームがまだ開いているが、JVM がデータを待機している場合 (遅いディスク、ソケット接続)、ブロックread()されます(実際にはハングしていません)。

ストリームはどこから取得していますか?- を確認してavailable()ください。ただし、CPU を使い果たすループで呼び出さないでください。

int最後に: /byteへのキャストcharは ASCII 文字に対してのみ機能しReaderますInputStream

于 2012-07-05T19:48:29.330 に答える
2

ドキュメントを読む

InputStream が閉じられていない場合、 read() は InputStream にデータが追加されるまで待機します。

ソケットでこれをやっていると思いますか?これは、これが発生する最も一般的な領域です。

"入力ストリームからデータの次のバイトを読み取ります。値のバイトは、0 から 255 の範囲の int として返されます。ストリームの最後に達したために使用可能なバイトがない場合、値 -1 が返されます。これは、メソッドは、入力データが利用可能になるか、ストリームの終わりが検出されるか、例外がスローされるまでブロックされます。」

于 2012-07-05T19:47:28.877 に答える
0

Android の Apache Commons にも同じ問題があります...入力ストリームの read() コマンドが何らかの理由で永久にハングします。いいえ、「データが利用可能になるまで」ブロックするだけではありません...私のデバッグ情報は、利用可能な100文字がいくつかあることを示しています...それでも、読み取り時にランダムにブロックするだけです。ただし、telnet サーバーに何かを送信するたびに、ブロックが突然解放され、任意の時点で突然停止/ブロックされるまで、数文字の読み取りが続行されます!

Apache Commons ライブラリ内に何らかのバグがあると思います! できることはあまりないので、これは本当に面倒です...読み取りコマンドなどのタイムアウトはありません...

編集:私はそれを回避することができました... TelNetClient.setReaderThread(false)を設定することにより...明らかに、スレッドが入力データを処理する限り存在するライブラリ内にバグがあります...無効にすると機能します私にとっては大丈夫です!

于 2012-07-18T14:04:56.690 に答える