"Soy yo otravez."

"¡Hola, Ellie!"

"Hoy me gustaría contarles todo acerca de BufferedReader y BufferedWriter ".

"Ya me hablaste de ellos. Realmente no son tan complicados".

"Está bien. Entonces dime cómo funciona BufferedReader ".

" BufferedReader es como un convertidor de 110/220V".

"Tiene que pasar al constructor BufferedReader el objeto Reader del que se leerán los datos. Un objeto BufferedReader lee grandes cantidades de datos del Reader y los almacena internamente en un búfer. Es por eso que usar un BufferedReader para leer desde un Reader es más rápido que leer directamente de un Reader ".

"Así es. ¿Y qué pasa con BufferedWriter ?"

"Es pan comido. Supongamos que escribimos en un FileWriter . Los datos se escriben en el disco de inmediato. Si escribimos pequeños fragmentos de datos con frecuencia, golpearemos mucho el disco, lo que ralentizará mucho el programa. Pero si usamos un BufferedWriter como un 'convertidor', entonces la operación de escritura es mucho más rápida. Cuando escribe en un BufferedWriter , guarda los datos en un búfer interno. Cuando el búfer está lleno, escribe los datos en el Escritor como un solo trozo grande. Esto es mucho más rápido".

"Hmm. En el clavo. Pero, ¿qué has olvidado?"

"Después de que haya terminado de escribir, debe llamar al método flush() en el objeto BufferedWriter para forzarlo a enviar cualquier dato que aún esté en el búfer al Writer ".

"¿Y qué más?"

"¿Qué más? ¡Oh! Siempre que el búfer no se haya escrito en el Escritor , los datos se pueden eliminar y/o reemplazar".

"¡Amigo! ¡Estoy impresionado! ¡Eres un experto! Bueno, entonces te hablaré de algunas clases nuevas:  ByteArrayStream y PrintStream ".

"Por ejemplo, ByteArrayInputStream y ByteArrayOutputStream ".

"Estas clases son un poco como StringReader y StringWriter . Excepto que StringReader lee caracteres ( char ) de una cadena ( String ), pero InputStream lee bytes de una matriz de bytes ( ByteArray )".

StringWriter escribe caracteres ( char ) en una cadena, mientras que ByteArrayOutputStream escribe bytes en una matriz de bytes interna. Cuando escribe en un StringWriter , su cadena interna crece y cuando escribe en un ByteArrayOutputStream , su matriz de bytes interna también se expande dinámicamente.

"Recuerda el ejemplo que te dieron en la última lección:"

Lectura del objeto lector y escritura en el objeto escritor:
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 StringReader reader = new StringReader(test);

 StringWriter writer = new StringWriter();

 executor(reader, writer);

 String result = writer.toString();

 System.out.println("Result: "+ result);
}

public static void executor(Reader reader, Writer writer) throws Exception
{
 BufferedReader br = new BufferedReader(reader);
 String line;
 while ((line = br.readLine()) != null) {
 StringBuilder sb = new StringBuilder(line);
 String newLine = sb.reverse().toString();

 writer.write(newLine);
 }
}

"Así es como se vería si funcionara usando bytes en lugar de caracteres:"

Lectura de un objeto InputStream y escritura en un objeto OutputStream:
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 InputStream inputStream = new ByteArrayInputStream(test.getBytes());

 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

 executor(inputStream, outputStream);

 String result = new String(outputStream.toByteArray());
 System.out.println("Result: "+ result);
}

public static void executor(InputStream inputStream, OutputStream outputStream) throws Exception
{
 BufferedInputStream bis = new BufferedInputStream(inputStream);
 while (bis.available() > 0)
 {
  int data = bis.read();
  outputStream.write(data);
 }
}

"Todo es igual que en el ejemplo anterior. Excepto que reemplazamos String con ByteArray, Reader con InputStream y Writer con OutputStream".

"Los únicos otros dos pasos son convertir String en ByteArray y viceversa. Como puede ver, esto se hace con bastante facilidad:"

Convertir una cadena en un ByteArray y viceversa
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 byte[] array = test.getBytes();

 String result = new String(array);
 System.out.println("Result: "+ result);
}

"Para obtener los bytes que ya se agregaron a un ByteArrayOutputStream, llame al método toByteArray ()".

"Ah. Las similitudes con StringReader/StringWriter son bastante fuertes, especialmente después de que me las señalaras. Gracias, Ellie, por una lección realmente interesante".

"¿A dónde vas con tanta prisa? Todavía tengo un pequeño regalo para ti. Quiero contarte sobre la clase PrintStream".

"¿PrintStream? Esa es la primera vez que escucho de esa clase".

"Sí. Especialmente, si no cuenta el hecho de que lo ha estado usando desde el primer día de sus estudios de Java. ¿Recuerda System.out ? Bueno, System.out es una variable estática (clase) del sistema clase, y su tipo es... ¡ PrintStream ! Aquí es de donde provienen todos estos métodos de impresión, impresión, etc.".

"Wow. Qué interesante. De alguna manera nunca consideré eso. Cuéntame más".

"Bien. Está bien, escuchen. La clase PrintStream se inventó para una salida legible. Consiste casi en su totalidad en métodos print e println. Mire esta tabla:"

Métodos Métodos
void print(boolean b) void println(boolean b)
void print(char c) void println(char c)
void print(int c) void println(int c)
void print(long c) void println(long c)
void print(float c) void println(float c)
void print(double c) void println(double c)
void print(char[] c) void println(char[] c)
void print(String c) void println(String c)
void print(Object obj) void println(Object obj)
void println()
PrintStream format (String format, Object ... args)
PrintStream format (Locale l, String format, Object ... args)

"También hay varios métodos de formato para que pueda generar datos usando una cadena de formato. Por ejemplo:"

Convertir una cadena en un ByteArray y viceversa
String name = "Kolan";
int age = 25;
System.out.format("My name is %s. My age is %d.", name, age);
Salida de pantalla:
My name is Kolan. My age is 25.

"Sí, lo recuerdo. Ya estudiamos el método de formato de la clase String".

"Eso es todo por ahora."

"Gracias, Ellie".