"¡Hola, amigo! Ahora te contaré sobre dos interfaces: InputStream y OutputStream . Se declaran como clases abstractas, pero si profundizas más, puedes ver que son esencialmente interfaces . Casi todos sus métodos son abstractos, excepto por algunos métodos insignificantes. Son muy parecidos al " guardaespaldas " que consideramos antes".

Estas son interfaces muy interesantes. Por ahora, los llamaré deliberadamente interfaces , para que comprenda por qué los necesitamos. Y luego hablaremos de por qué en realidad son clases abstractas.

"Está bien. Entonces, ¿qué son estas interfaces?"

"Te lo diré sin más preámbulos".

Java tiene esta cosa interesante llamada « flujo ». Una corriente es una entidad muy simple. Y su simplicidad es la clave para una forma muy poderosa de intercambiar datos. Hay dos tipos de flujos: flujos de lectura y flujos de escritura .

Como probablemente ya haya adivinado, puede escribir datos en una secuencia para escribir archivos . Tiene un método de escritura para esto. Puede leer datos de una secuencia para leer . Tiene un método de lectura () para esto.

InputStream  es la interfaz para un flujo que admite la lectura. Define la siguiente capacidad: «los bytes se pueden leer de mí».

De manera similar, OutputStream , un OutputStream es una interfaz para un flujo que admite escritura. Define la siguiente habilidad: «se me pueden escribir bytes».

"¿Eso es todo?"

"Más o menos. Pero el punto es que Java tiene muchas clases que pueden funcionar con InputStream y OutputStream . Por ejemplo, desea leer un archivo del disco y mostrar su contenido en la pantalla. Nada podría ser más fácil".

Para leer datos de un archivo en el disco, tenemos la clase especial FileInputStream , que implementa la interfaz InputStream . ¿Quiere escribir estos datos en otro archivo? Para ello contamos con la clase FileOutputStream , que implementa la interfaz OutputStream . El siguiente código muestra lo que debe hacer para copiar datos de un archivo a otro.

Código
public static void main(String[] args) throws IOException
{
 InputStream inStream = new FileInputStream("c:/source.txt");
 OutputStream outStream = new FileOutputStream("c:/result.txt");

 while (inStream.available() > 0)
 {
  int data = inStream.read(); //read one byte from the input stream
  outStream.write(data); //write that byte to the other stream.
 }

 inStream.close(); //close the streams
 outStream.close();
}

Imagine que hemos escrito una clase y  le hemos agregado las capacidades InputStream  y  OutputStream .

Si implementamos correctamente estas interfaces, las instancias de nuestra clase ahora se pueden guardar o leer desde un archivo. Simplemente leyendo su contenido usando el método de lectura . O se pueden cargar desde un archivo creando un objeto y usando el método de escritura para escribir el contenido del archivo.

"¿Tal vez un ejemplo?"

"Seguro."

Código Descripción
class MyClass
{
private ArrayList<Integer> list;
}
Para simplificar, imagine que nuestra clase contiene un objeto, una ArrayList que contiene números enteros.

Ahora le agregaremos métodos de lectura y escritura.

Código Descripción
class MyClass
{
private ArrayList<Integer> list;
public void write(int data)
{
list.add(data);
}
public int read()
{
int first = list.get(0);
list.remove(0);
return first;
}

public int available()
{
return list.size();
}
}
Ahora nuestra clase implementa el método de lectura , que hace posible leer secuencialmente todo el contenido de la lista .

Y el método de escritura , que te permite escribir valores en nuestra lista.

Por supuesto, esto no es una implementación de las interfaces InputStream y OutputStream, pero es muy similar.

"Sí, entiendo. Entonces, ¿cómo se guarda el contenido de dicho objeto en un archivo?"

"Dejame darte un ejemplo:"

Escribir un objeto MyClass en un archivo
public static void main(String[] args)
{
 MyClass myObject = new MyClass();
 OutputStream outStream = new FileOutputStream ("c:/my-object-data.txt");

 while (myObject.available() > 0)
 {
  int data = myObject.read(); //read one int from the input stream
  outStream.write(data); //write that int to the other stream.
 }

 outStream.close();
}
Leer un objeto MyClass de un archivo
public static void main(String[] args)
{
 InputStream inStream = new FileInputStream("c:/my-object-data.txt");
 MyClass myObject = new MyClass();

 while (inStream.available() > 0)
 {
  int data = inStream.read(); //read one int from the input stream
  myObject.write(data); //write that int to the other stream.
 }

 inStream.close(); //close the streams
}

"¡Santo Dios! Realmente es muy similar a trabajar con InputStream/OutputStream. ¡Las transmisiones son geniales!"

"¡Y algo más!"