PipedReader y PipedWriter (y sus correspondientes streams de entrada y salida PipedInputStream y PipedOutputStream) implementan los componentes de entrada y salida de una tuber�a.
Las tuber�as se utilizan para canalizar la salida de un programa (o thread) a la entrada de otro programa (o thread)
�Por qu� son �tiles?
Consideremos una clase que implementa varias utilidades de manipulaci�n de strings como ordenaci�n o inversi�n de texto. Ser�a bonito que la salida de uno de estos m�todos puediera ser usada como entrada del otro para que pudieramos encadenar una serie de llamadas a m�todos que realizan un funci�n de gran importancia. Por ejemplo, podr�amos invertir todas las palabras de una lista, ordenarlas, y volver a invertirlas para crear una lista de palabr�s r�tmicas.
Sin los streams de tuber�as, el programa deber�a almacenar los resultados en alg�n lugar (como en un fichero o en la memoria) entre cada paso, como se ve aqu�:

Con los streams de tuber�as, la salida de un m�todo puede ser dirigida hacia la entrada del siguiente, como se muestra en esta figura:

Luego investigaremos un programa que implementa lo que representa el diagrama de la figura anterior.
Este programa usa PipedReader y PipedWriter para conectar la entrada y la salida de sus m�todos reverse y sort para crear una lista de palabras r�tmicas. Este programa se compone de varias clases. Esta secci�n muestra y explica s�lo los elementos del programa que leen y escriben en las tuber�as. Sigue los siguientes enlaces al c�digo para ver el programa completo.
Primero, echemos un vistazo a la secuencia de llamada de los m�todos reverse y sort desde el m�todo main en la clase RhymingWords.
FileReader words = new FileReader("words.txt");
Reader rhymingWords = reverse(sort(reverse(words)));
La llamada m�s interna a reverse toma un FileReader abierto sobre el fichero words.txt que contiene una lista de palabras. El valor devuelto por reverse se pasa a sort, cuyo valor de retorno es pasado a otra llamada a reverse.
Echemos un vistazo al m�todo reverse; el m�todo sort es similiar y lo entenderemos una vez que comprendamos reverse.
public static Reader reverse(Reader source) {
BufferedReader in = new BufferedReader(source);
PipedWriter pipeOut = new PipedWriter();
PipedReader pipeIn = new PipedReader(pipeOut);
PrintWriter out = new PrintWriter(pipeOut);
new ReverseThread(out, in).start();
return pipeIn;
}
Las sentencias en negrita de reverse crean los dos puntos finales de una tuber�a --un PipedWriter y un PipedReader-- y los conecta construyendo el PipedReader "sobre" el PipedWriter.
Cualquier cosa escrita en el PipedWriter puede ser le�da desde el PipedReader.
Las formas de conexi�n de tuber�as se ilustran aqu�:.

reverse arranca un ReverseThread que escribe su salida en el PipedWriter y devuelve el PipedReader al llamador.
Entonces el llamador preprara un thread de ordenaci�n para leerla.
El m�todo sort es exactamente lo mismo, excepto en que crea y arranca un SortThread.
�Usar Streams para Envolver otros Streams
El m�todo reverse contiene alg�n c�digo interesante; en particular estas dos sentencias:
BufferedReader in = new BufferedReader(source); ... PrintWriter out = new PrintWriter(pipeOut);
La primera l�nea abre un BufferedReader sobre source, el argumento a invertir (un Reader).
Esto esencialmente "envuelve" source en un BufferedReader.
El programa lee desde el BufferedReader, que a su vez lee desde source.
El programa hace esto para poder usar el m�todo de conveniencia readLine de BufferedReader.
De forma similar, el PipedWriter es envuelto en un PrintWriter para que el programa pueda usar el m�todo de conveniencia println de PrintWriter.
Frecuentemente veremos estreams envueltos de esta forma para as� combinar las distintas caracter�sticas de varios streams.
|
Intenta esto:
Escribe otra versi�n de este programa que use inputstreams y outputstreams en vez de readers y writers. Aqu� puedes ver las soluciones: |