Pregunta

¿Por qué se cuelga el siguiente método?

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
    }
}
¿Fue útil?

Solución

Respondiendo a mi propia pregunta: tienes que llamar a buf.clear () entre read s. Presumiblemente, read está colgado porque el búfer está lleno. El código correcto es

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

Otros consejos

Supongo que es un punto muerto. El in.read (buf) bloquea el CharBuffer y evita la llamada out.append (buf).

Suponiendo que CharBuffer utiliza bloqueos (de algún tipo) en la implementación. ¿Qué dice la API sobre la clase CharBuffer?

Edit: Lo siento, una especie de cortocircuito en mi cerebro ... lo confundí con otra cosa.

Los CharBuffers no funcionan con los lectores y escritores de la forma más limpia que se podría esperar. En particular, no existe el método Writer.append (CharBuffer buf) . El método llamado por el fragmento de pregunta es Writer.append (CharSequence seq) , que simplemente llama a seq.toString () . El método CharBuffer.toString () devuelve el valor de cadena del búfer, pero no agota el búfer. La llamada subsiguiente a Reader.read (CharBuffer buf) obtiene un búfer ya completo y, por lo tanto, devuelve 0, lo que obliga a que el ciclo continúe indefinidamente.

A pesar de que se siente como un bloqueo, en realidad está agregando el contenido del búfer de la primera lectura al escritor cada vez que pasa por el bucle. Por lo tanto, comenzarás a ver una gran cantidad de resultados en tu destino o el búfer interno del escritor aumentará, dependiendo de cómo se implemente el escritor.

Por muy molesto que sea, recomendaría una implementación char [] solo porque la solución CharBuffer termina generando al menos dos nuevos char [] cada paso a través del bucle.

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

Recomendaría solo usar esto si necesitas admitir la conversión entre dos codificaciones de caracteres, de lo contrario sería preferible una implementación ByteBuffer / Channel o byte [] / IOStream incluso si estás canalizando caracteres.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top