Frage

Warum wird die folgende Methode hängen?

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
    }
}
War es hilfreich?

Lösung

Die Beantwortung meiner Frage: Sie haben buf.clear() zwischen reads zu nennen. Vermutlich hängt read, da der Puffer voll ist. Der richtige Code ist

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();
    }
}

Andere Tipps

Ich würde davon ausgehen, dass es eine Sackgasse ist. Die in.read (buf) sperrt die CharBuffer und verhindert, dass die out.append (buf) -Aufruf.

Das ist unter der Annahme, dass CharBuffer verwendet Schlösser (irgendeiner Art) bei der Umsetzung. Was sagt die API über die Klasse CharBuffer?

Edit: Sorry, eine Art Kurzschluss in meinem Gehirn ... ich verwirrte es mit etwas anderem

.

CharBuffers arbeiten nicht mit Leser und Schreiber so sauber wie man erwarten könnte. Insbesondere gibt es keine Writer.append(CharBuffer buf) Methode. Die Methode, mit der Frage Schnipsel genannt wird Writer.append(CharSequence seq), die seq.toString() gerade anruft. Die CharBuffer.toString() Methode macht den String-Wert des Puffers zurück, aber nicht den Puffer entleeren. Der nachfolgende Aufruf von Reader.read(CharBuffer buf) erhält einen bereits vollen Puffer und deshalb liefert 0, zwingt die Schleife auf unbestimmte Zeit fortzusetzen.

Obwohl dies wie ein Hang fühlt, ist es in der Tat der erste Lese der Pufferinhalt an den Schriftsteller Anfügen jeder durch die Schleife. So werden Sie entweder starten eine Menge Ausgabe in Ihrem Ziel zu sehen oder den internen Puffer des Schreibers wird wachsen, je nachdem, wie die Schreiber implementiert wird.

Wie ärgerlich, wie es ist, würde ich einen char [] Umsetzung empfehlen, wenn nur, weil die CharBuffer Lösung aufwickelt Gebäude mindestens zwei neue char [] jeder durch die Schleife.

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);
    }
}

Ich würde empfehlen, nur diese zu verwenden, wenn Sie zwischen zwei Zeichenkodierungen unterstützen müssen Umwandlung, da sonst ein ByteBuffer / Kanal oder byte [] / Iostream Implementierung vorzuziehen wäre, selbst wenn Sie Rohr Zeichen sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top