Leer y escribir archivos en Java

L

Introducción

En este artículo, profundizaremos en la lectura y escritura de archivos en Java.

Al programar, ya sea que esté creando una aplicación móvil, una aplicación web o simplemente escribiendo scripts, a menudo tiene la necesidad de leer o escribir datos en un archivo. Estos datos pueden ser datos de caché, datos que recuperó para un conjunto de datos, una imagen o cualquier otra cosa que se le ocurra.

En este tutorial, mostraremos las formas más comunes en las que puede leer y escribir archivos en Java.

Java proporciona varias API (también conocidas como E / S de Java) para leer y escribir archivos desde sus versiones iniciales. Con versiones posteriores, Java I / O se ha mejorado, simplificado y mejorado para admitir nuevas funciones.

Antes de pasar a algunos ejemplos reales, sería útil comprender las clases disponibles para usted que manejarán la lectura y escritura de datos en archivos. En las siguientes secciones, proporcionaremos una breve descripción general de las clases de E / S de Java y explicaremos lo que hacen, luego veremos los flujos de NIO de Java y, finalmente, mostraremos algunos ejemplos de lectura y escritura de datos en archivos.

Flujos de E / S

Hay dos tipos de transmisiones que puede utilizar para interactuar con archivos:

  • Flujos de personajes
  • Secuencias de bytes

Para cada uno de los tipos de transmisión anteriores, hay varias clases de soporte enviadas con Java, que veremos rápidamente a continuación.

Flujos de personajes

Los flujos de caracteres se utilizan para leer o escribir el tipo de datos de los caracteres. Veamos las clases más utilizadas. Todas estas clases se definen en java.io paquete.

Aquí hay algunas clases que debe saber que se pueden utilizar para leer datos de caracteres:

  • Lector: Una clase abstracta para leer un flujo de caracteres.
  • InputStreamReader: Clase utilizada para leer el flujo de bytes y se convierte en flujo de caracteres.
  • FileReader: Una clase para leer los caracteres de un archivo.
  • BufferedReader: Este es un envoltorio sobre el Reader clase que admite capacidades de almacenamiento en búfer. En muchos casos, esta es la clase más preferible para leer datos porque se pueden leer más datos del archivo en una read() llamada, reduciendo el número de operaciones de E / S reales con el sistema de archivos.

Y aquí hay algunas clases que puede utilizar para escribir datos de caracteres a un archivo:

  • Escritor: Esta es una clase abstracta para escribir los flujos de caracteres.
  • OutputStreamWriter: Esta clase se utiliza para escribir secuencias de caracteres y también convertirlas en secuencias de bytes.
  • FileWriter: Una clase para escribir caracteres en el archivo.
  • Escritor en búfer: Este es un envoltorio sobre el Writer class, que también admite capacidades de almacenamiento en búfer. Esta es la clase más preferible para escribir datos en un archivo, ya que se pueden escribir más datos en el archivo en una write() llamada. Y como el BufferedReader, esto reduce el número total de operaciones de E / S con el sistema de archivos.

Secuencias de bytes

Los flujos de bytes se utilizan para leer o escribir datos de bytes con archivos. Esto es diferente de antes en la forma en que tratan los datos. Aquí trabaja con bytes sin procesar, que pueden ser caracteres, datos de imagen, datos Unicode (que necesitan 2 bytes para representar un carácter), etc.

En esta sección, echaremos un vistazo a las clases más utilizadas. Todas estas clases se definen en java.io paquete.

Aquí están las clases utilizadas para leer los datos del byte:

  • Flujo de entrada: Una clase abstracta para leer los flujos de bytes.
  • FileInputStream: Una clase para simplemente leer bytes de un archivo.
  • BufferedInputStream: Este es un envoltorio sobre InputStream que admite capacidades de almacenamiento en búfer. Como vimos en los flujos de caracteres, este es un método más eficiente que FileInputStream.

Y aquí están las clases utilizadas para escribir los datos de bytes:

  • Flujo de salida: Una clase abstracta para escribir flujos de bytes.
  • FileOutputStream: Una clase para escribir bytes sin procesar en el archivo.
  • ByteOutputStream: Esta clase es una envoltura de OutputStream para admitir las capacidades de almacenamiento en búfer. Y nuevamente, como vimos en los flujos de caracteres, este es un método más eficiente que FileOutputStream gracias al almacenamiento en búfer.

Secuencias de Java NIO

Java NIO es una API de E / S sin bloqueo que se introdujo en Java 4 y se puede encontrar en el java.nio paquete. En términos de rendimiento, esta es una gran mejora en la API para operaciones de E / S.

Los búferes, selectores y canales son los tres componentes principales de Java NIO, aunque en este artículo nos centraremos estrictamente en el uso de las clases NIO para interactuar con archivos, y no necesariamente los conceptos detrás de la API.

Como este tutorial trata sobre la lectura y escritura de archivos, discutiremos solo las clases relacionadas en esta breve sección:

  • Camino: Esta es una estructura jerárquica de la ubicación de un archivo real y generalmente se usa para ubicar el archivo con el que desea interactuar.
  • Caminos: Esta es una clase que proporciona varios métodos de utilidad para crear un Path de un URI de cadena dado.
  • Archivos: Esta es otra clase de utilidad que tiene varios métodos para leer y escribir archivos sin bloquear la ejecución en subprocesos.

Con estas pocas clases, puede interactuar fácilmente con los archivos de una manera más eficiente.

La diferencia entre Java I / O y NIO

La principal diferencia entre estos dos paquetes es que el read() y write() Los métodos de Java IO son llamadas de bloqueo. Con esto queremos decir que el hilo que llama a uno de estos métodos se bloqueará hasta que los datos se hayan leído o escrito en el archivo.

Por otro lado, en el caso de NIO, los métodos son sin bloqueo. Esto significa que los subprocesos de llamada pueden realizar otras tareas (como leer / escribir datos de otra fuente o actualizar la interfaz de usuario) mientras read o write Los métodos esperan a que se complete su operación. Esto puede resultar en un aumento significativo del rendimiento si está tratando con muchas solicitudes de E / S o muchos datos.

Ejemplos de lectura y escritura de archivos de texto

En las secciones anteriores, hemos discutido las diferentes API proporcionadas por Java y ahora es el momento de usar estas clases de API en algún código.

El código de ejemplo a continuación maneja la lectura y escritura de archivos de texto usando las diversas clases que detallamos anteriormente. Para simplificar las cosas y proporcionar una mejor comparación de los métodos reales que se utilizan, la entrada y la salida serán las mismas entre los ejemplos.

Nota: Para evitar cualquier confusión en la ruta del archivo, el código de ejemplo leerá y escribirá desde un archivo en el directorio de inicio del usuario. El directorio de inicio del usuario se puede encontrar usando System.getProperty("user.home");, que es lo que usamos en nuestros ejemplos.

Leer y escribir con FileReader y FileWriter

Empecemos por usar el FileReader y FileWriter clases:

String directory = System.getProperty("user.home");
String fileName = "sample.txt";
String absolutePath = directory + File.separator + fileName;

// Write the content in file 
try(FileWriter fileWriter = new FileWriter(absolutePath)) {
    String fileContent = "This is a sample text.";
    fileWriter.write(fileContent);
    fileWriter.close();
} catch (IOException e) {
    // Cxception handling
}

// Read the content from file
try(FileReader fileReader = new FileReader(absolutePath)) {
    int ch = fileReader.read();
    while(ch != -1) {
        System.out.print((char)ch);
        fileReader.close();
    }
} catch (FileNotFoundException e) {
    // Exception handling
} catch (IOException e) {
    // Exception handling
}

Ambas clases aceptan una cadena, que representa la ruta al archivo en sus constructores. También puede pasar un File objeto así como un FileDescriptor.

los write() El método escribe una secuencia de caracteres válida, ya sea un String, un char[]. Además, puede escribir un solo char representado como un int.

los read() El método lee y devuelve carácter por carácter, lo que nos permite utilizar los datos leídos en un while bucle, por ejemplo.

¡No olvide cerrar ambas clases después de su uso!

Leer y escribir con BufferedReader y BufferedWriter

Utilizando BufferedReader y BufferedWriter clases:

String directory = System.getProperty("user.home");
String fileName = "sample.txt";
String absolutePath = directory + File.separator + fileName;

// Write the content in file 
try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(absolutePath))) {
    String fileContent = "This is a sample text.";
    bufferedWriter.write(fileContent);
} catch (IOException e) {
    // Exception handling
}

// Read the content from file
try(BufferedReader bufferedReader = new BufferedReader(new FileReader(absolutePath))) {
    String line = bufferedReader.readLine();
    while(line != null) {
        System.out.println(line);
        line = bufferedReader.readLine();
    }
} catch (FileNotFoundException e) {
    // Exception handling
} catch (IOException e) {
    // Exception handling
}

Leer y escribir con FileInputStream y FileOutputStream

Utilizando FileInputStream y FileOutputStream clases:

String directory = System.getProperty("user.home");
String fileName = "sample.txt";
String absolutePath = directory + File.separator + fileName;

// write the content in file 
try(FileOutputStream fileOutputStream = new FileOutputStream(absolutePath)) {
    String fileContent = "This is a sample text.";
    fileOutputStream.write(fileContent.getBytes());
} catch (FileNotFoundException e) {
    // exception handling
} catch (IOException e) {
    // exception handling
}

// reading the content of file
try(FileInputStream fileInputStream = new FileInputStream(absolutePath)) {
    int ch = fileInputStream.read();
    while(ch != -1) {
        System.out.print((char)ch);
        ch = fileInputStream.read();
    }
} catch (FileNotFoundException e) {
    // exception handling
} catch (IOException e) {
    // exception handling
}

Leer y escribir con BufferedInputStream y BufferedOutputStream

Utilizando BufferedInputStream y BufferedOutputStream clases:

String directory = System.getProperty("user.home");
String fileName = "sample.txt";
String absolutePath = directory + File.separator + fileName;

// write the content in file 
try(BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(absolutePath))) {
    String fileContent = "This is a sample text.";
    bufferedOutputStream.write(fileContent.getBytes());
} catch (IOException e) {
    // exception handling
}

// read the content from file
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(absolutePath))) {
    int ch = bufferedInputStream.read();
    while(ch != -1) {
        System.out.print((char)ch);
        ch = bufferedInputStream.read();
    }
} catch (FileNotFoundException e) {
    // exception handling
} catch (IOException e) {
    // exception handling
}

Lectura y escritura con clases de Java.nio

Utilizando el java.nio clases:

String directory = System.getProperty("user.home");
String fileName = "sample.txt";

String content = "This is a sample text.";
Path path = Paths.get(directory, fileName);

try {
    Files.write(path, content.getBytes(), StandardOpenOption.CREATE);
} catch (IOException e) {
    // exception handling
}

try {
    List<String> list = Files.readAllLines(path);
    list.forEach(line -> System.out.println(line));
} catch (IOException e) {
    // exception handling
}

Otra forma de recuperar el contenido a través del Files clase, que es más importante si no está leyendo datos de texto, es utilizar la readAllBytes método para leer los datos en una matriz de bytes:

try { 
    byte[] data = Files.readAllBytes(path);
    System.out.println(new String(data));
} catch (IOException e) {
    // exception handling
}

En caso de que esté interesado en utilizar transmisiones con java.nio, también puede utilizar los métodos siguientes proporcionados por el Files class, que funcionan igual que los flujos que cubrimos anteriormente en el artículo:

Files.newBufferedReader(path)
Files.newBufferedWriter(path, options)
Files.newInputStream(path, options)
Files.newOutputStream(path, options)

Conclusión

En este artículo, hemos cubierto las formas más comunes de leer y escribir datos en un archivo utilizando tanto el paquete Java I / O como el paquete Java NIO más nuevo. Siempre que sea posible, recomendamos utilizar las clases Java NIO para operaciones de archivos debido a su API sin bloqueo, y además el código es un poco más fácil de mantener y leer.

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad