3

バッファリングされたリーダーから読み取る次の例があります。

while ((inputLine = input.readLine()) != null) {
   System.out.println("I got a message from a client: " + inputLine);
}

ループ内のコードはprintln、バッファリングされたリーダーに何かが現れるたびに実行されます (inputこの場合)。私の場合、クライアント アプリケーションがソケットに何かを書き込むと、(サーバー アプリケーションの) ループ内のコードが実行されます。

しかし、私はそれがどのように機能するのか理解していません。inputLine = input.readLine()バッファリングされたリーダーに何かが表示されるまで待機し、そこに何かが表示されると戻りtrue、ループ内のコードが実行されます。ただし、いつnull返品できますか。

別の質問があります。上記のコードはthrows Exception、スレッドの実行メソッドでこのコードを使用するメソッドから取得したものです。そして、コンパイラが不平を言うthrows Exception前に配置しようとするとrun、オーバーライドされたメソッドは例外をスローしません。なしではthrows exception、コンパイラから別の苦情があります。報告されていない例外です。それで、なにかお手伝いできますか?

4

9 に答える 9

5

反対側のソケットが閉じている場合、リーダーは null 文字列を返す必要があります。これはあなたが探している条件です。例外を処理するには、読み取りループを try/catch ブロックでラップします。

 try {
   while ((inputLine = input.readLine()) != null) {
     System.out.println("I got a message from a client: " + inputLine);
   }
 }
 catch (IOException e) {
   System.err.println("Error: " + e);
 }

Java のソケットからの読み取り/ソケットへの書き込みに関するこのチュートリアルが役立つ場合があります。

于 2010-03-23T13:20:40.290 に答える
3

最初の質問:

しかし、私はそれがどのように機能するのか理解していません。inputLine = input.readLine() は、バッファリングされたリーダーに何かが表示されるまで待機し、そこに何かが表示されると true を返し、ループ内のコードが実行されます。ただし、null を返すことができる場合。

BufferedReader.readLine() true成功しても戻りません。読み取った行を含む文字列を返します。ストリームの最後に到達すると、 が返されますnull

2 番目の質問:

上記のコードは、Exception をスローするメソッドから取得したもので、スレッドの run メソッドでこのコードを使用します。そして、実行前に throws Exception を配置しようとすると、コンパイラーは不平を言います:オーバーライドされたメソッドは例外をスローしません。throws 例外がなければ、コンパイラから別の苦情があります。報告されていない例外です。それで、なにかお手伝いできますか?

コードをtry/catch ブロックでラップする必要があります。キャッチされた例外を処理したくない場合は、その部分を空白のままにしておきます (お勧めしません)。

try {
    while ((inputLine = input.readLine()) != null) {
        System.out.println("I got a message from a client: " + inputLine);
    }
} catch (Exception e) {
    //handle exception
}
于 2010-03-23T13:30:39.733 に答える
1

リーダーの readLine() は、何かを読み取った場合は文字列値を返し、まだ何も読み取っていない場合は空の文字列を返し、接続が閉じている場合は null を返します。

IO 関数を使用してコード ブロックを try/catch で囲み、エラーを適切に処理することをお勧めします。

于 2010-03-23T13:21:43.150 に答える
0

inputリーダーは、リスナーであるソケットに接続されます。つまり、着信メッセージをリッスンし続けます。

2 番目の質問については、メソッド内に try/catch ブロックを配置し、例外をキャッチして処理する必要があります。投げ直さないでください。

于 2010-03-23T13:18:48.750 に答える
0

しかし、私はそれがどのように機能するのか理解していません。.... バッファリングされたリーダーに何かが表示されるまで待機し、そこに何かが表示されると true を返します

いいえ、式 (inputLine = input.readLine()) の値、inputLine 自体を返します。inputLine は null と比較されます。

于 2010-03-23T13:22:01.310 に答える
0

「EOF(End Of File)」に到達するとnullを返します。これはネットワーク ソケットから読み取っているため、(サーバーまたはクライアントによって) ソケットが切断されたときにファイルの終わりが作成されますが、実際に EOF が表示される前に例外が発生する可能性があります。

于 2010-03-23T13:22:55.213 に答える
0

これが宿題ではない場合は、Apache Commons IOUtilsを参照してください。

BufferedReader を作成せず、InputStream で停止すると仮定します。

String results = IOUtils.toString(inputStream);
System.out.println(results);
于 2010-03-23T13:24:58.610 に答える
0

あなたはいくつかの良い答えを受け取りました。例外をキャッチしてローカルで処理するだけです。これを他のコードに渡す必要があるが、run()メソッドがチェック例外を許可していないためにできない場合は、何らかの種類の RuntimeException で例外をラップできます。run メソッドが Thread で直接実行されている場合 (おそらく Runnable であるため)、ラップされた例外の再スローに注意する必要があります。

からの結果については、読み取るものがなくなったときにreadLine()返さnullれます。ソケットの場合、これは反対側がソケットを正常に閉じたときです (OS が別の種類のソケット クローズ通知を送信するため、突然の終了または不正なクローズは通常、コードで例外になります)。

でソケットをラップしているので、注意が必要ですjava.io.BufferedReader。あらゆる種類の製品コードでこれを使用する場合は、十分に注意する必要があります。

危険なのは、BufferedReader が読み取り中の例外をうまく処理できないことです。これは、ソケットでタイムアウトを有効にして、コードがオペレーティング システムから定期的な例外を自動的に受信する場合に特に問題になります。タイムアウト (またはその他の例外) は、リーダー内のバッファーがいっぱいになっているときに発生する可能性があります。例外の後でオブジェクトを再利用しようとすると、バッファ内の以前の内容は無視されます。以前に受信したパケットは黙って失われ、それらのバイトを取得する方法はありません。

ソケットが失われたことを意味しない、他の種類のソケット例外があることに注意してください。たとえば、 の定義を見てくださいjava.io.InterruptedIOException。これには、最新の I/O (読み取りまたは書き込み) 要求で正常に転送されたバイト数を報告するパブリック変数があります。これは、IO 操作を再度実行して、パケットの残りのバイトを取得または送信できることを意味します。

例外が発生した場合に、リーダーとソケットをすぐに閉じるように設計されている場合、メソッドは正しく機能します。

ソケットから読み取る適切な方法は、ソケット ストリームを直接使用するか、NIO (ByteBuffers など) を使用するか、これらの低レベル クラスを適切に抽象化した適切に作成されたネットワーク ライブラリを使用することです (いくつかのオープン ソースのクラスが利用可能です)。

于 2010-03-23T15:36:07.483 に答える
0
while ((inputLine = input.readLine()) != null) {

式の各部分を見てください。

input.readLine()

ストリームの終わりに到達した場合 (またはエラー時に例外をスローした場合) に null になる文字列を返します。

inputLine = input.readLine()

この文字列を inputLine に割り当てます

((inputLine = input.readLine()) != null)

割り当てられた文字列が null (ストリームの終わり) でないことを確認します。

于 2010-03-23T13:27:47.740 に答える