"Olá, amigo! Agora vou falar sobre duas interfaces: InputStream e OutputStream . Elas são declaradas como classes abstratas, mas se você se aprofundar verá que são essencialmente interfaces . Quase todos os seus métodos são abstratos, exceto por alguns métodos insignificantes. Eles são muito parecidos com o " guarda-costas " que consideramos anteriormente."

Estas são interfaces muito interessantes. Por enquanto, vou chamá-los deliberadamente de interfaces , para que você entenda por que precisamos deles. E então falaremos sobre por que elas são realmente classes abstratas.

"Ok. Então, o que são essas interfaces?"

"Eu vou te dizer sem mais delongas."

Java tem uma coisa interessante chamada « fluxo ». Um fluxo é uma entidade muito simples. E sua simplicidade é a chave para uma maneira muito poderosa de trocar dados. Existem dois tipos de fluxos: fluxos para leitura e fluxos para gravação .

Como você provavelmente já adivinhou, você pode gravar dados em um fluxo para gravar arquivos . Tem um método de gravação para isso. Você pode ler dados de um fluxo para leitura . Tem um método read () para isso.

InputStream  é a interface para um fluxo que oferece suporte à leitura. Define a seguinte habilidade: «bytes podem ser lidos de mim».

Da mesma forma, OutputStream , um OutputStream é uma interface para um fluxo que oferece suporte à gravação. Define a seguinte habilidade: «bytes can be write to me».

"É isso?"

"Praticamente. Mas o ponto principal é que Java tem várias classes que podem funcionar com InputStream e OutputStream . Por exemplo, você deseja ler um arquivo do disco e exibir seu conteúdo na tela. Nada poderia ser mais fácil."

Para ler dados de um arquivo em disco, temos a classe especial FileInputStream , que implementa a interface InputStream . Deseja gravar esses dados em outro arquivo? Para isso, temos a classe FileOutputStream , que implementa a interface OutputStream . O código a seguir mostra o que você precisa fazer para copiar dados de um arquivo para outro.

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 escrevemos uma classe e adicionamos as  habilidades InputStream  e  OutputStream a ela.

Se implementarmos corretamente essas interfaces, as instâncias de nossa classe agora poderão ser salvas ou lidas de um arquivo. Simplesmente lendo seu conteúdo usando o método read . Ou eles podem ser carregados de um arquivo criando um objeto e usando o método write para gravar o conteúdo do arquivo.

"Talvez um exemplo?"

"Claro."

Código Descrição
class MyClass
{
private ArrayList<Integer> list;
}
Para simplificar, imagine que nossa classe contém um objeto, um ArrayList que contém inteiros.

Agora vamos adicionar métodos de leitura e gravação a ele

Código Descrição
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();
}
}
Agora nossa classe implementa o método read , que possibilita a leitura sequencial de todo o conteúdo de list .

E o método write , que permite escrever valores em nossa lista.

Claro, isso não é uma implementação das interfaces InputStream e OutputStream, mas é muito semelhante.

"Sim, eu entendo. Então, como você salva o conteúdo de tal objeto em um arquivo?"

"Deixe-me lhe dar um exemplo:"

Gravar um objeto MyClass em um arquivo
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();
}
Ler um objeto MyClass de um arquivo
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
}

"Caramba! Realmente é muito parecido com trabalhar com InputStream/OutputStream. Streams são ótimos!"

"E então alguns!"