JavaRush /Blog Java /Random-ES /E/S en Java. Clases FileInputStream, FileOutputStream, Bu...

E/S en Java. Clases FileInputStream, FileOutputStream, BufferedInputStream

Publicado en el grupo Random-ES
¡Hola! En la conferencia de hoy continuaremos la conversación sobre flujos de entrada y salida en Java, o Java I/O (“entrada-salida”) para abreviar. Esta no es la primera conferencia sobre este tema y no será la última :) Da la casualidad de que Java como lenguaje ofrece muchas oportunidades para trabajar con entrada/salida. Hay bastantes clases que implementan esta funcionalidad, por lo que las dividimos en varias clases para que no te confundas al principio :) E/S en Java.  Clases FileInputStream, FileOutputStream, BufferedInputStream - 1En clases anteriores tocamos BufferedReader , así como las clases abstractas InputStream y OutputStream y varias. descendientes. Hoy veremos 3 clases nuevas: FileInputStream , FileOutputStream y BufferedInputStream .

Clase FileOutputStream

El objetivo principal de la clase FileOutputStream es escribir bytes en un archivo. Nada complicado :) FileOutputStream es una de las implementaciones de la clase abstracta OutputStream . En el constructor, los objetos de esta clase toman la ruta al archivo de destino (en el que se deben escribir los bytes) o un objeto de la clase File. Veamos ambos ejemplos:
public class Main {

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


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "¡Hola! ¡Bienvenido a JavaRush, el mejor sitio para aquellos que quieren convertirse en programadores!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Al crear un objeto, Fileespecificamos en el constructor la ruta donde debe ubicarse. No es necesario crearlo con antelación: si no existe, el programa lo creará él mismo. Puedes hacerlo sin crear un objeto adicional y simplemente pasar una cadena con la dirección:
public class Main {

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


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "¡Hola! ¡Bienvenido a JavaRush, el mejor sitio para aquellos que quieren convertirse en programadores!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
El resultado en ambos casos será el mismo. Podemos abrir nuestro archivo y ver allí:

¡Hola! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
Sin embargo, hay una advertencia aquí. Intente ejecutar el código del ejemplo anterior varias veces seguidas y luego mire el archivo y responda la pregunta: ¿cuántas líneas ve escritas en él? Solo uno. Pero ejecutaste el código varias veces. Sin embargo, resulta que los datos se sobrescribieron cada vez, reemplazando los antiguos. ¿Qué pasa si no estamos satisfechos con esto y necesitamos una grabación secuencial? ¿Qué pasa si queremos escribir nuestro saludo en un archivo tres veces seguidas? Aquí todo es sencillo. Dado que el lenguaje en sí no puede saber qué tipo de comportamiento necesitamos en cada caso, FileOutputStreampuede pasar un parámetro adicional al constructor: boolean append. Si su valor es verdadero , los datos se escribirán al final del archivo. Si es falso (y el valor predeterminado es falso ), los datos antiguos se borrarán y se escribirán datos nuevos. Probemos y ejecutemos nuestro código modificado tres veces:
public class Main {

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


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "¡Hola! ¡Bienvenido a JavaRush, el mejor sitio para aquellos que quieren convertirse en programadores!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Resultado en el archivo:

¡Hola! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
¡Hola! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
¡Hola! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
¡Otra cosa! Tenga en cuenta esta característica cuando utilice clases de E/S. En un momento, tuve que sentarme durante horas en tareas para entender a dónde iban mis datos antiguos de los archivos :) Y, por supuesto, como en el caso de otras clases de E/S, no te olvides de liberar recursos a través del archivo close().

Clase FileInputStream

La clase tiene FileInputStreamel propósito opuesto: leer bytes de un archivo. Al igual que FileOutputStreamlas herencias OutputStream, esta clase deriva de la clase abstracta InputStream. Escribamos varias líneas de texto en nuestro texto " test.txt ":

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
E/S en Java.  Clases FileInputStream, FileOutputStream, BufferedInputStream - 2 Esto es lo que significa la implementación de la lectura de datos de un archivo usando FileInputStream:
public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Leemos un byte del archivo, convertimos los bytes leídos en caracteres y los enviamos a la consola. Y aquí está el resultado en la consola:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

Clase BufferedInputStream

Creo que, dado el conocimiento de conferencias anteriores, puedes decir fácilmente por qué se necesita la clase BufferedInputStreamy qué ventajas tiene sobre FileInputStream:) Ya nos hemos encontrado con transmisiones en búfer, así que intenta adivinar (o recordar) antes de continuar leyendo :) Secuencias en búfer se necesitan principalmente para optimizar la E/S. Acceder a una fuente de datos, como leer un archivo, es una operación que requiere mucho rendimiento. Y acceder al archivo para leer un byte cada vez es un desperdicio. Por lo tanto, BufferedInputStreamlee datos no un byte a la vez, sino en bloques y los almacena temporalmente en un búfer especial. Esto nos permite optimizar el funcionamiento del programa reduciendo el número de accesos al archivo. Veamos cómo se ve:
public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Aquí hemos creado un objeto BufferedInputStream. Acepta un objeto o cualquiera de sus sucesores como entrada InputStream, por lo que el anterior FileInputStreamservirá. Toma el tamaño del búfer en bytes como parámetro adicional. Ahora, gracias a esto, los datos del archivo se leerán no un byte a la vez, ¡sino 200 a la vez! Imagínese cuánto hemos reducido el número de accesos a archivos. Para comparar el rendimiento, puede tomar un archivo de texto grande de varios megabytes de tamaño y comparar cuánto tiempo lleva leerlo y enviarlo a la consola en milisegundos usando FileInputStreamy BufferedInputStream. A continuación se muestran ambos ejemplos de código:
public class Main {

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

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

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

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
Al leer un archivo de 1,5 MB en mi computadora, FileInputStreamhizo el trabajo en ~3500 milisegundos, pero aquí BufferedInputStreamhizo el trabajo en ~1700 milisegundos. Como puede ver, la transmisión almacenada en búfer optimizó el rendimiento del programa 2 veces. :) Continuaremos estudiando clases de E/S. ¡Hasta pronto!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION