"Ciao, Amigo! Ora ti parlerò di due interfacce: InputStream e OutputStream . Sono dichiarate come classi astratte, ma se scavi più a fondo puoi vedere che sono essenzialmente interfacce . Quasi tutti i loro metodi sono astratti, ad eccezione di alcuni metodi insignificanti, che sono molto simili alla " guardia del corpo " che abbiamo considerato prima.

Queste sono interfacce molto interessanti. Per ora, le chiamerò deliberatamente interfacce , in modo da capire perché ne abbiamo bisogno. E poi parleremo del perché in realtà sono classi astratte.

"Okay. Allora, quali sono queste interfacce?"

"Te lo dirò senza ulteriori indugi."

Java ha questa cosa interessante chiamata « stream ». Un flusso è un'entità molto semplice. E la sua semplicità è la chiave per un modo molto potente di scambiare dati. Esistono due tipi di flussi: flussi per la lettura e flussi per la scrittura .

Come probabilmente hai già intuito, puoi scrivere dati in un flusso per la scrittura di file . Ha un metodo di scrittura per questo. È possibile leggere i dati da un flusso per la lettura . Ha un metodo read () per questo.

InputStream  è l'interfaccia per un flusso che supporta la lettura. Definisce la seguente abilità: «i byte possono essere letti da me».

Allo stesso modo, OutputStream , un OutputStream è un'interfaccia per un flusso che supporta la scrittura. Definisce la seguente abilità: «mi si possono scrivere byte».

"Questo è tutto?"

"Più o meno. Ma il punto è che Java ha un sacco di classi che possono funzionare con InputStream e OutputStream . Ad esempio, vuoi leggere un file dal disco e visualizzarne il contenuto sullo schermo. Niente potrebbe essere più semplice."

Per leggere i dati da un file su disco, abbiamo la speciale classe FileInputStream , che implementa l' interfaccia InputStream . Vuoi scrivere questi dati in un altro file? Per questo, abbiamo la classe FileOutputStream , che implementa l' interfaccia OutputStream . Il codice seguente mostra cosa è necessario fare per copiare i dati da un file a un altro.

Codice
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();
}

Immagina di aver scritto una classe e di avervi aggiunto le  abilità InputStream  e  OutputStream .

Se abbiamo implementato correttamente queste interfacce, le istanze della nostra classe ora possono essere salvate o lette da un file. Semplicemente leggendo il loro contenuto usando il metodo read . Oppure possono essere caricati da un file creando un oggetto e utilizzando il metodo write per scrivere il contenuto del file.

"Forse un esempio?"

"Sicuro."

Codice Descrizione
class MyClass
{
private ArrayList<Integer> list;
}
Per semplicità, immagina che la nostra classe contenga un oggetto, un ArrayList che contiene numeri interi.

Ora aggiungeremo i metodi di lettura e scrittura ad esso

Codice Descrizione
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();
}
}
Ora la nostra classe implementa il metodo read , che rende possibile la lettura sequenziale dell'intero contenuto di list .

E il metodo write , che ti consente di scrivere valori nella nostra lista.

Naturalmente, questa non è un'implementazione delle interfacce InputStream e OutputStream, ma è molto simile.

"Sì, ho capito. Quindi come si salva il contenuto di un oggetto del genere in un file?"

"Lasciate che vi faccia un esempio:"

Scrive un oggetto MyClass in un file
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();
}
Legge un oggetto MyClass da un file
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 cielo! È davvero molto simile a lavorare con InputStream/OutputStream. I flussi sono dolci!"

"E poi qualche!"