CodeGym /Blog Java /Random-ES /Practica trabajar con las clases BuffreredReader y InputS...
Autor
Jesse Haniel
Lead Software Architect at Tribunal de Justiça da Paraíba

Practica trabajar con las clases BuffreredReader y InputStreamReader

Publicado en el grupo Random-ES
¡Hola! La lección de hoy se dividirá en dos partes por conveniencia. Repetiremos algunos temas antiguos que tocamos anteriormente y consideraremos algunas características nuevas :) Empecemos con el primero. Ya tienes una clase como BufferedReadermuchas veces. Espero que no hayas tenido tiempo de olvidar esta afirmación:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Antes de seguir leyendo, trate de recordar de qué es responsable cada componente — System.in, InputStreamReader, BufferedReader— y por qué es necesario. ¿Recuerdas? Si no, no te preocupes. :) Si has olvidado algo, vuelve a leer esta lección , que está dedicada a las clases de lectores. Recordaremos brevemente lo que cada uno de ellos puede hacer. System.in— este es un flujo para recibir datos desde el teclado.  En principio, solo sería suficiente para implementar la lógica requerida para leer el texto. Pero, como recordará, System.insolo puede leer bytes, no caracteres:

public class Main {

   public static void main(String[] args) throws IOException { 

       while (true) { 
           int x = System.in.read(); 
           System.out.println(x); 
       } 
   } 
} 
Si ejecutamos este código e ingresamos la letra cirílica "É", la salida será:

Й
208
153
10 
Los caracteres cirílicos ocupan 2 bytes en la memoria y se muestran en la pantalla. El número 10 es la representación decimal de un carácter de salto de línea, es decir, de pulsar Intro. Leer bytes es un placer, por lo que su uso System.inno es muy conveniente. Para leer correctamente las letras cirílicas (y otras), usamos InputStreamReadercomo envoltorio:

public class Main { 

   public static void main(String[] args) throws IOException { 

       InputStreamReader reader = new InputStreamReader(System.in); 
       while (true) { 
           int x = reader.read(); 
           System.out.println(x); 
       } 
   } 
} 
Ingresamos la misma letra "É", pero el resultado es diferente esta vez:

Й 
1049 
10
InputStreamReaderconvirtió dos bytes (208 y 153) al único número 1049. Esto es lo que significa leer caracteres. 1049 corresponde a la letra cirílica "É". Fácilmente podemos convencernos de que esto es cierto:

public class Main { 

   public static void main(String[] args) throws IOException { 
       char x = 1049; 
       System.out.println(x); 
   } 
} 
Salida de la consola:

Й
Y como forBufferedReader(y en general BufferedAnythingYouWant), las clases almacenadas en búfer se utilizan para optimizar el rendimiento. Acceder a una fuente de datos (archivo, consola, recurso web) es bastante costoso en términos de rendimiento. Por lo tanto, para reducir el número de accesos, BufferedReaderlee y acumula datos en un búfer especial, y los obtenemos de allí. Como resultado, la cantidad de veces que se accede a la fuente de datos se reduce, ¡posiblemente en varios órdenes de magnitud! Otra de BufferedReaderlas características de y su ventaja sobre el ordinario , es el método InputStreamReaderextremadamente útil , que lee líneas enteras de datos, no números individuales. readLine()Esto, por supuesto, es muy conveniente cuando se trata de textos extensos. Así es como se ven las líneas de lectura:

public class Main { 

   public static void main(String[] args) throws IOException { 

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
       String s = reader.readLine(); 
       System.out.println ("The user entered the following text:"); 
       System.out.println(s); 
       reader.close(); 
   } 
}

BufferedReader+InputStreamReader is faster than InputStreamReader alone 
The user entered the following text: 
BufferedReader+InputStreamReader is faster than InputStreamReader alone
Practica trabajar con las clases BuffreredReader y InputStreamReader - 2Por supuesto, BufferedReaderes muy flexible. No estás limitado a trabajar con el teclado. Por ejemplo, puede leer datos directamente desde la web, simplemente pasando la URL requerida a un lector:

public class URLReader { 

   public static void main(String[] args) throws Exception { 

       URL oracle = new URL("https://www.oracle.com/index.html"); 
       BufferedReader in = new BufferedReader( 
               new InputStreamReader(oracle.openStream())); 

       String inputLine; 
       while ((inputLine = in.readLine()) != null) 
           System.out.println(inputLine); 
       in.close(); 
   } 
}
Puede leer datos de un archivo pasando la ruta del archivo:

public class Main { 

   public static void main(String[] args) throws Exception { 

       FileInputStream fileInputStream = new FileInputStream("testFile.txt"); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream)); 

       String str; 

       while ((str = reader.readLine()) != null)   { 
           System.out.println (str); 
       } 

       reader.close(); 
   } 
}

Sustitución de System.out

Ahora echemos un vistazo a una capacidad interesante que no hemos tocado antes. Como seguramente recordará, la Systemclase tiene dos campos estáticos: System.iny  System.out. Estos hermanos gemelos son objetos de corriente. System.ines un InputStream. Y System.out es un PrintStream. Ahora mismo hablaremos de  System.out. Si entramos en el Systemcódigo fuente de la clase, vemos esto:

public final class System { 
……………... 
public final static PrintStream out = null; 
 ………… 
} 
Por lo tanto,  System.out  es simplemente una variable estática ordinaria de laSystem clase. No tiene nada de mágico :) La outvariable es una PrintStreamreferencia. Aquí hay una pregunta interesante: cuando System.out.println()se ejecuta, ¿por qué exactamente la salida va a la consola y no a otro lugar? ¿Y esto se puede cambiar de alguna manera? Por ejemplo, supongamos que queremos leer datos de la consola y escribirlos en un archivo de texto. ¿Es posible implementar esto de alguna manera simplemente usando  System.outen lugar de clases adicionales de lectores y escritores? De hecho, lo es :) ¡Y podemos hacerlo aunque la System.outvariable esté marcada con el finalmodificador!  Practica trabajar con las clases BuffreredReader y InputStreamReader - 3Entonces, ¿qué necesitamos para que esto suceda? En primer lugar, necesitamos un nuevo PrintStreamobjeto para reemplazar el actual. El objeto actual, establecido en elSystemclass por defecto, no sirve para nuestros propósitos: apunta a la consola. Debe crear uno nuevo que apunte a un archivo de texto, el "destino" de nuestros datos. Segundo, necesitamos entender cómo asignar un nuevo valor a la System.outvariable. No puede usar un operador de asignación simple, porque la variable está marcada final. Vamos a trabajar hacia atrás desde el final. Da la casualidad de que la Systemclase tiene el método que necesitamos: setOut(). Toma un PrintStreamobjeto y lo establece como destino para la salida. ¡Eso es justo lo que necesitamos! Todo lo que queda es crear un PrintStreamobjeto. Esto también es fácil:

PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
El código completo se verá así:

public class SystemRedirectService { 

   public static void main(String arr[]) throws FileNotFoundException 
   { 
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
       /* Save the current value of System.out in a separate variable so that later 
       we can switch back to console output */ 

       PrintStream console = System.out; 
       // Assign a new value to System.out 
       System.setOut(filePrintStream); 
       System.out.println("This line will be written to the text file"); 

       // Restore the old value of System.out 
       System.setOut(console); 
       System.out.println("But this line will be output to the console!"); 
   } 
}
Como resultado, la primera cadena se escribe en el archivo de texto y la segunda se muestra en la consola :) Puede copiar este código en su IDE y ejecutarlo. Abra el archivo de texto y verá que la cadena se ha escrito con éxito allí :) Con esto, nuestra lección ha llegado al final. Hoy recordamos cómo trabajar con flujos y lectores. Recordamos cómo se diferencian entre sí y aprendimos sobre algunas capacidades nuevas de System.out, que hemos usado en casi todas las lecciones :) ¡Hasta las próximas lecciones!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION