"Começaremos com fluxos para entrada/saída de arquivo. Mas primeiro as coisas mais importantes."

Existem duas classes para leitura e gravação de arquivos: FileInputStream e FileOutputStream . Como você provavelmente já adivinhou, FileInputStream pode ler bytes sequencialmente de um arquivo e FileOutputStream pode gravar bytes sequencialmente em um arquivo. Aqui estão os métodos que essas classes têm:

Método O que o método faz
FileInputStream(String fileName);
— Este é o construtor. Permite especificar o nome de um arquivo em disco, do qual o objeto criado irá ler os dados.
int read();
— Este método lê um byte do arquivo e o retorna. O valor de retorno é ampliado para um int.
int available();
— Este método retorna o número de bytes não lidos (disponíveis).
void close();
— Este método «fecha» o fluxo. Você chama isso quando terminar de trabalhar com o fluxo.
O objeto então executa as operações de manutenção necessárias para fechar o arquivo, etc.
Neste ponto, você não pode ler mais dados do fluxo.

Apenas por diversão, vamos calcular a soma de todos os bytes em um arquivo. Aqui está a aparência do código:

Somar todos os bytes em um arquivo
public static void main(String[] args) throws Exception
{
 //Create a FileInputStream object bound to «c:/data.txt».
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 long sum = 0;

 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  int data = inputStream.read(); //Read the next byte
  sum +=  data; //Add it to the running total
 }
 inputStream.close(); // Close the stream

 System.out.println(sum); // Display the sum on the screen.
}

"Já examinamos algo assim. Como o FileOutputStream é organizado?"

"OK. Veja isto:"

Método O que o método faz
FileOutputStream (String fileName);
"Este é o construtor. Ele permite que você especifique o nome de um arquivo no disco, no qual o objeto criado gravará dados."
void write(int data);
"Este método grava o próximo byte, truncando os dados para um byte."
void flush();
"Os dados a serem gravados geralmente são coletados primeiro em grandes blocos na memória e depois gravados apenas no disco."

O comando flush força todas as informações não salvas a serem gravadas no disco.

void close();
"Este método «fecha» o fluxo. Você o chama quando terminar de trabalhar com o fluxo."
O objeto então executa as operações de limpeza necessárias para fechar o arquivo, etc.

Você não pode mais gravar dados no fluxo e o flush é chamado automaticamente.

"É isso?"

"Sim, na verdade só existe um método para escrever: write(). Ele grava apenas um byte por vez. Mas permite que você escreva quanta informação quiser no arquivo."

A programação é um processo de dividir uma tarefa grande e complexa em muitas tarefas pequenas. Essencialmente, o mesmo processo está acontecendo aqui: a leitura e a gravação de grandes blocos de dados são divididas em leitura e gravação em partes pequenas - um byte por vez.

Veja como você pode usar essas classes para copiar um arquivo no disco:

Copiar um arquivo no disco
public static void main(String[] args) throws Exception
{
 //Create a stream to read bytes from a file
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 //Create a stream to write bytes to a file
 FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  int data = inputStream.read(); // Read the next byte into the data variable
  outputStream.write(data); // and write it to the second stream
 }

 inputStream.close(); //Close both streams. We don't need them any more.
 outputStream.close();
}

"Obrigado, Rishi. Finalmente entendi como esse código realmente funciona."