JavaRush /Blog Java /Random-ES /Practica trabajar con las clases BufferedReader y InputSt...

Practica trabajar con las clases BufferedReader y InputStreamReader

Publicado en el grupo Random-ES
¡Hola! La conferencia de hoy se dividirá en dos partes. Repetiremos algunos de los temas antiguos que ya hemos tocado antes y veremos algunas características nuevas :) Practica trabajar con las clases BuffrredReader y InputStreamReader - 1Comencemos con el primero. La repetición es la madre del aprendizaje :) Ya has utilizado una clase como BufferedReader. Espero que no hayas olvidado este comando todavía:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Antes de seguir leyendo, intente recordar de qué System.in, InputStreamReader, BufferedReaderes responsable cada componente ( ) y para qué son necesarios. ¿Sucedió? Si no, no te preocupes :) Si a estas alturas has olvidado algo, vuelve a leer esta conferencia dedicada a los lectores. Recordemos brevemente lo que puede hacer cada uno de ellos. System.ines un hilo para recibir datos desde el teclado. En principio, para implementar la lógica de lectura del texto, nos bastaría con uno. Pero, como recordarás, System.insólo 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 "Y" en la consola, el resultado será así:

Й
208
153
10
Los caracteres cirílicos ocupan 2 bytes en la memoria, que se muestran en la pantalla (y el número 10 es la representación en bytes de un salto de línea, es decir, presionar Enter). Leer bytes es un gran placer, por lo que usarlo System.inen su forma pura será un inconveniente. Para leer letras cirílicas (y no solo) que sean comprensibles para todos, utilizamos 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);
       }
   }
}
Si ingresamos la misma letra “Y” en la consola, el resultado esta vez será diferente:

Й
1049
10
InputStreamReaderconvirtió los dos bytes leídos (208, 153) en un solo número 1049. Esto es lectura por caracteres. 1049 corresponde a la letra “Y”, la cual se puede verificar fácilmente:

public class Main {

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

       char x = 1049;
       System.out.println(x);
   }
}
Salida de consola:

Й
Bueno, en cuanto a BufferedReader'a (y en general, BufferedAnything), las clases almacenadas en búfer se utilizan para optimizar el rendimiento. Acceder a una fuente de datos (archivo, consola, recurso en Internet) es una operación bastante costosa en términos de rendimiento. Por lo tanto, para reducir el número de llamadas de este tipo, BufferedReaderlee y acumula datos en un búfer especial, desde donde luego podemos recibirlos. Como resultado, el número de llamadas a la fuente de datos se reduce varias veces o incluso decenas de veces. Otra característica adicional de BufferedReader'a y su ventaja sobre regular InputStreamReader' es el método extremadamente útil readLine()que lee datos como cadenas completas en lugar de números individuales. Esto, por supuesto, añade mucha comodidad a la hora de implementar, por ejemplo, texto de gran tamaño. Así es como se vería leer una línea:

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("Пользователь ввел следующий текст:");
       System.out.println(s);
       reader.close();
   }
}

BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Пользователь ввел следующий текст:
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Practica trabajar con las clases BuffrredReader y InputStreamReader - 2Por supuesto, BufferedReaderes un mecanismo muy flexible y permite trabajar no sólo con el teclado. Puede leer datos, por ejemplo, directamente desde Internet simplemente pasando la URL requerida al 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 pasándole la ruta:

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 veamos una posibilidad interesante que no hemos mencionado antes. Como probablemente recuerdes, Systemhay dos campos estáticos en la clase: System.iny System.out. Estos hermanos gemelos son objetos de clase hilo. System.in- clase abstracta InputStream. Una System.outclase PrintStream. Ahora hablaremos específicamente de System.out. Si nos adentramos en el código fuente de la clase System, veremos esto:

public final class System {

……………...

public final static PrintStream out = null;

  …………

}
Entonces, System.outsolo una variable de clase estática normalSystem . No hay magia en esto :) La variable outpertenece a la clase PrintStream. Aquí hay una pregunta interesante: ¿por qué, al ejecutar código, System.out.println()el resultado aparece en la consola y no en otro lugar? ¿Y es posible cambiar esto de alguna manera? Por ejemplo, queremos leer datos de la consola y escribirlos en un archivo de texto. ¿Es posible implementar de alguna manera dicha lógica sin usar clases adicionales de lector y escritor, sino simplemente usando System.out? Aún así es posible :) Y aunque la variable System.outestá designada por un modificador final, ¡aún podemos hacerlo! Practica trabajar con las clases BuffrredReader y InputStreamReader - 3Entonces, ¿qué necesitamos para esto? En primer lugar , necesitamos un nuevo objeto de clase PrintStreamen lugar del actual. El objeto actual instalado en la clase Systempor defecto no nos conviene: apunta a la consola. Necesitamos crear uno nuevo que apunte a un archivo de texto como el "destino" de nuestros datos. En segundo lugar , es necesario comprender cómo asignar un nuevo valor a una variable System.out. No puedes hacerlo así porque está marcado final. Empecemos por el final. La clase Systemcontiene exactamente el método que necesitamos: setOut(). Toma un objeto como entrada PrintStreamy lo establece como punto de salida. ¡Justo lo que necesitamos! Todo lo que queda es crear el objeto PrintStream. Esto también es fácil de hacer:

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

       /*Сохраним текущее significado System.out в отдельную переменную, чтобы потом
       можно было переключиться обратно на вывод в консоль*/
       PrintStream console = System.out;

       // Присваиваем System.out новое significado
       System.setOut(filePrintStream);
       System.out.println("Эта строка будет записана в текстовый файл");

       // Возвращаем System.out старое significado
       System.setOut(console);
       System.out.println("А эта строка - в консоль!");
   }
}
Como resultado, la primera línea se escribirá en un archivo de texto y la segunda se enviará a la consola :) Puede copiar este código a su IDE y ejecutarlo. Al abrir el archivo de texto, verá que la línea requerida se ha escrito correctamente :) Con esto concluye la conferencia. Hoy recordamos cómo trabajar con transmisiones y lectores, recordamos en qué se diferencian entre sí y aprendimos sobre las nuevas funciones System.outque usamos en casi todas las lecciones :) ¡Nos vemos en las próximas conferencias!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION