0

次のメソッドがハングするのはなぜですか?

public void pipe(Reader in、Writer out){
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while(in.read(buf)> = 0){
      out.append(buf.flip());
    }
}
4

3 に答える 3

1

私自身の質問に答える:あなたはsのbuf.clear()間で電話しなければなりませんread。おそらく、readバッファがいっぱいであるためにハングしています。正しいコードは

public void pipe(Reader in、Writer out){
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while(in.read(buf)> = 0){
      out.append(buf.flip());
      buf.clear();
    }
}
于 2008-09-24T15:07:41.370 に答える
0

CharBuffersは、期待するほどきれいにリーダーとライターで動作しません。特に、Writer.append(CharBuffer buf)方法はありません。質問スニペットによって呼び出されるメソッドは、です。これはWriter.append(CharSequence seq)、を呼び出すだけseq.toString()です。このCharBuffer.toString()メソッドはバッファの文字列値を返しますが、バッファを排出しません。の後続の呼び出しReader.read(CharBuffer buf)は、すでに満杯のバッファを取得するため、0を返し、ループを無期限に続行します。

これはハングのように感じますが、実際には、ループを通過するたびに、最初の読み取りのバッファーの内容をライターに追加しています。したがって、ライターの実装方法に応じて、宛先で多くの出力が表示されるようになるか、ライターの内部バッファーが大きくなります。

面倒ですが、CharBufferソリューションがループを通過するたびに少なくとも2つの新しいchar []を構築することになるという理由だけで、char[]の実装をお勧めします。

public void pipe(Reader in, Writer out) throws IOException {
    char[] buf = new char[DEFAULT_BUFFER_SIZE];
    int count = in.read(buf);
    while( count >= 0 ) {
        out.write(buf, 0, count);
        count = in.read(buf);
    }
}

2つの文字エンコーディング間の変換をサポートする必要がある場合にのみ、これを使用することをお勧めします。そうでない場合は、文字をパイプする場合でも、ByteBuffer/Channelまたはbyte[]/IOStreamの実装が望ましいでしょう。

于 2012-03-09T02:54:03.027 に答える
0

I would assume that it is a deadlock. The in.read(buf) locks the CharBuffer and prevents the out.append(buf) call.

That is assuming that CharBuffer uses locks (of some kind)in the implementation. What does the API say about the class CharBuffer?

Edit: Sorry, some kind of short circuit in my brain... I confused it with something else.

于 2008-09-24T15:08:45.377 に答える