Introducción al paquete Java NIO
Este tutorial presenta el paquete Java NIO
. Ya tenemos un paquete java.io
para realizar operaciones de lectura/escritura, pero java.nio
nos permite trabajar de manera diferente con características y funcionalidades adicionales.
¿Cómo? Vamos a sumergirnos en sus detalles.
Introducción al paquete Java NIO
Java New Input/Output (NIO
) es una estructura de manejo de archivos de alto rendimiento y una API de red. El paquete java.nio
tiene todas las clases NIO
; no reemplaza las clases de entrada/salida (IO
) basadas en secuencias en el paquete java.io
.
El NIO
de Java se introdujo a partir de la versión JDK 4
y funciona como una alternativa a java.io
con algunas características y funcionalidades adicionales para trabajar con Entrada/Salida (IO
) de manera diferente en comparación con la Entrada/Salida estándar (IO
).
Ya sabemos que el paquete java.io
tiene todas las clases necesarias que podemos usar para las operaciones de E/S de Java, mientras que java.nio
introduce clases de buffer
que se pueden usar en todas las API de Java NIO
.
Puede que tengas una duda: cuando ya tenemos un paquete java.io
, ¿cuál es el motivo de introducir uno nuevo llamado java.nio
?
Razones principales para usar el paquete Java NIO
Preferimos usar el paquete java.nio
por dos razones.
-
El paquete
java.nio
utiliza un enfoque orientado al búfer que nos permite avanzar y retroceder en el búfer. Utiliza un bloque de memoria (también llamado búfer) para leer y almacenar datos en caché, a los que se accede rápidamente desde el búfer siempre que sea necesario; también podemos escribir datos en el búfer. -
El paquete
java.nio
puede realizar operaciones de entrada/salida (IO
) sin bloqueo. Aquí, sin bloqueo significa que puede leer los datos/información que encuentre listo.Por ejemplo, tenemos un hilo que le pide al canal que lea los datos/información del búfer; el hilo va para otras operaciones en ese marco de tiempo y continúa de nuevo donde dejó el trabajo. Mientras tanto, el proceso de lectura se completa y aumenta el rendimiento general.
La principal diferencia entre NIO
y IO
es que NIO
no bloquea, mientras que IO
bloquea.
Podemos priorizar el uso de Java NIO
sobre el paquete IO
siempre que busquemos un enfoque orientado al búfer y operaciones de entrada/salida de alta velocidad.
NIO
, debe comprender el paquete Java IO
.Componentes principales del paquete Java NIO
Tiene los siguientes componentes principales para funcionar correctamente.
-
Buffer
: como el paquetejava.nio
está orientado a búfer, tiene búferes para tipos de datos primitivos. Los búferes se utilizan como contenedores donde podemos leer datos desde/hacia el búfer para su posterior procesamiento mediante el uso de un canal. -
Channel
: la clase de canal dejava.nio
es similar a los streams (streamsIO
) utilizados para la comunicación bidireccional. Mediante el uso de canales, podemos realizar operaciones de entrada/salida sin bloqueo; también podemos leer/escribir datos desde/hasta el búfer desde los canales.Los canales se utilizan como una puerta de enlace donde la conexión a varias entidades se describe mediante canales que pueden realizar operaciones
IO
sin bloqueo. -
Selector
: podemos usar selectores para realizar operacionesIO
sin bloqueo. Un selector (un objeto) monitorea más de un canal para los eventos.Podemos decir que los selectores seleccionan los canales listos para realizar operaciones de Entrada/Salida.
Use el paquete NIO
para leer y escribir en un archivo en Java
A continuación se muestra la representación gráfica de varias clases que se pueden utilizar para realizar diferentes operaciones.
Puede leer sobre java.nio
en detalle aquí, pero en este tutorial nos centramos en leer desde un archivo y escribir en operaciones relacionadas con archivos; ver los siguientes ejemplos.
Código de ejemplo (para leer de un archivo):
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class readFromFile {
public static void main(String[] args) {
Path filePath = Paths.get("file.txt");
Charset charSet = Charset.forName("ISO-8859-1");
try {
List<String> lines = Files.readAllLines(filePath, charSet);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e);
}
}
}
Código de ejemplo (para escribir en un archivo):
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class writeToFile {
public static void main(String[] args) {
Path filePath = Paths.get("file.txt");
String message = "We have overwritten the file";
Charset charSet = Charset.forName("ISO-8859-1");
try {
Files.write(filePath, message.getBytes());
List<String> lines = Files.readAllLines(filePath, charSet);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e);
}
}
}
Salida (leer de un archivo y escribir en un archivo):
Leemos los datos del archivo especificado y los imprimimos en la línea de comando en el primer fragmento de código. En el segundo ejemplo de código, estamos escribiendo los datos (una pequeña cadena) en el archivo dado e imprimiéndolos en la pantalla para indicar lo que se está escribiendo en el archivo.
En el primer código de ejemplo, llamamos al método Paths.get()
el método de fábrica para la instancia Path
. En palabras simples, podemos decir que crea una instancia de Path
cada vez que llamamos al método estático llamado get()
de la clase java.nio.file.Paths
.
Este método toma una secuencia de cadenas (estas cadenas se unirán para formar una ruta) o una cadena como parámetros y la convierte en la instancia de Path
. Lanza InvalidPathException
si hay caracteres ilegales en la cadena que pasamos.
Al igual que File
, java.nio.file.Path
puede hacer referencia a una ruta relativa o absoluta dentro del sistema de archivos.
Charset
se utiliza para la codificación de caracteres. Estamos usando la codificación de caracteres ISO-8859-1
, pero puede especificar UTF-8
o cualquier otra que desee usar.
El método readAllLines()
lee un archivo de texto línea por línea. Guardamos los datos leídos en una List
de String
(ver el código).
Además, usamos un bucle for
para mostrar todas las líneas de lectura en la pantalla.
En el segundo ejemplo de código, toda la lógica es la misma excepto esta línea de código.
Files.write(filePath, message.getBytes());
El File.write()
es un método estático del paquete Java NIO
que se utiliza para escribir en el archivo especificado.