I/O Input/Output - Entrada/Salida de la información¶
Todo dato tiene un origen de entrada o un destino de salida (convenientemente en inglés: I/O).
- Input o entrada implica leer datos de una fuente
- Output o salida implica escribirlos en un destino.
Un programa trabaja con datos que provienen de una entrada la cual puede ser un teclado, un archivo en disco o un socket a través de la red. Así mismo un programa genera resultados enviándolos a una salida la cual puede ser la pantalla, un archivo en disco o un socket a través de la red. En Java, la conexión entre un programa y un origen o destino de datos se denomina flujo (en inglés: stream).

Un flujo de entrada (input stream) maneja los datos que fluyen hacia un programa. Un flujo de salida (output stream) maneja los datos que salen de un programa.

En las primeras versiones de Java el sistema de entrada/salida proporcionado en el paquete java.io era básico. En la versión 1.4 de Java se añadió un nuevo sistema de entrada/salida llamado java.NIO (New IO) para suplir algunas de sus deficiencias que posteriormente en Java 7 se mejoró aún más java.NIO. Entre las mejoras se incluyen permitir navegación de directorios sencillo, soporte para reconocer enlaces simbólicos, leer atributos de ficheros como permisos e información como última fecha de modificación, soporte de entrada/salida asíncrona y soporte para operaciones básicas sobre ficheros como copiar y mover ficheros.
Tipos de Datos - Caracteres y bytes¶
Existen dos tipos de flujos (streams) según el tipo de datos, flujos binarios y flujos de caracteres. Los tipos de datos que se pueden leer/escribir suelen ser bytes o caracteres y los métodos que se utilizan son similares, pero se utilizan clases diferentes.

Byte Streams (Flujos de bytes):¶
- Los byte streams operan a nivel de bytes, lo que significa que manejan datos de forma binaria, sin procesar.
- Son adecuados para leer y escribir datos binarios, como archivos de imágenes, archivos de audio, archivos ejecutables, etc.
- Los byte streams son más eficientes para leer y escribir datos binarios, ya que no realizan ninguna conversión de codificación.
Las clases principales
Clases principales de InputStream:
| Clase | Función |
|---|---|
| ByteArrayInputStream | Permite utilizar los buffers de memoria como InputStream |
| StringBufferInputStream | Convierte un string en InputStream |
| FileInputStream | Para leer la información del Archivo |
| PipeInputStream | Implementa el concepto de tubería (pipe) |
| SequenceInputStream | Convierte dos o más objetos InputStream en un único InputStream |
| BufferedInputStream | Añade la función de almacenamiento en buffer a las operaciones de lectura |
| DataInputStream | Proporciona una funcionalidad para leer de un flujo de tipos primitivos Java |
Clases principales de OutputStream:
| Clase | Función |
|---|---|
| ByteArrayOutputStream | Crea un buffer en la memoria, todos los datos transmitidos en el flujo se colocan en este buffer. |
| FileOutputStream | Para transmitir información de Archivo |
| PipeOutputStream | Implementa el concepto de tubería (pipe) |
| BufferedOutputStream | Añade la función de almacenamiento en buffer a las operaciones de escritura |
| DataOutputStream | Proporciona funcionalidad para escribir en archivos de tipo primitivo de Java |
Character Streams (Flujos de caracteres):¶
- Los character streams operan a nivel de caracteres, lo que significa que manejan datos como secuencias de caracteres Unicode.
- Son adecuados para leer y escribir datos de texto, ya que manejan la conversión entre bytes y caracteres de manera automática, utilizando la codificación adecuada (como UTF-8, UTF-16, etc.).
- Los character streams son más adecuados para trabajar con texto porque se encargan automáticamente de la codificación y decodificación, lo que los hace portables entre diferentes plataformas.
- Las clases principales para manejar estos flujos son las clases abstractas Reader y Writer.
Clases principales de Reader:
| Clase | Función |
|---|---|
| StringReader | Representa un stream que opera con cadenas |
| InputStreamReader | Es una clase puente entre el stream de char y el stream de bytes |
| FileReader | Proporciona soporte para la lectura de caracteres desde un archivo |
| PipedReader | Permite leer los caracteres de una pipe |
| BufferedReader | Añade la función de almacenamiento en buffer al stream para que no sea necesario acceder al sistema de archivos para cada operación de lectura |
| LineNumberReader | Mantiene un registro del número de línea desde el que se leen los caracteres |
Clases principales de Writer:
| Clase | Función |
|---|---|
| StringWriter | Permite escribir stream manipulados como cadenas |
| OutputStreamWriter | Es una clase puente entre el stream de char y el stream de bytes |
| FileWriter | Proporciona soporte para la escritura de caracteres en un archivo |
| PipedWriter | Permite escribir caracteres en una pipe |
| PrintWriter | Ofrece soporte para la impresión de caracteres con formato |
| BufferedWriter | Añade la funcionalidad de almacenamiento en buffer al flujo para que no haya necesidad de acceder al sistema de archivos para cada operación de escritura |
La siguiente figura muestra la jerarquía del paquete java.io.
Los streams pueden estar orientados a bytes u orientados a caracteres. Cada tipo tiene flujos de entrada y flujos de salida.

Flujos orientados a bytes¶
- Diseñado para entrada y salida de propósito general.
- Los datos pueden ser tipos de datos primitivos o bytes sin procesar.
Flujos orientados a caracteres¶
- Destinado a datos de caracteres.
- Los datos se transforman de/a caracteres Java de 16 bits utilizados dentro de los programas al formato utilizado externamente.
Ficheros¶
Un fichero es un conjunto lógico de información o de datos que se designa con un nombre y se configura como una unidad autónoma completa para el sistema o el usuario. Un archivo o fichero informático es un conjunto de bits que son almacenados en un dispositivo. Para poder acceder a ellos haremos uso de una ruta (path) ya sea relativa o absoluta.

Tipos de acceso a ficheros¶

-
Acceso secuencial: Una lectura secuencial implica tener que acceder a un elemento antes de acceder al siguiente, es decir, de una manera lineal (sin saltos). Las clases
InputStreamyOutputStreamson secuenciales. -
Acceso aleatorio: los ficheros de acceso aleatorio permiten acceder a sus datos de una forma aleatoria, esto es indicando una determinada posición desde la que leer/escribir. La clase
RandomAccessFilepermite el acceso aleatorio