Java - Arquivos e E / S

O pacote java.io contém quase todas as classes que você pode precisar para executar entrada e saída (E / S) em Java. Todos esses fluxos representam uma fonte de entrada e um destino de saída. O fluxo no pacote java.io suporta muitos dados, como primitivos, objetos, caracteres localizados, etc.

Corrente

Um fluxo pode ser definido como uma sequência de dados. Existem dois tipos de Streams -

  • InPutStream - O InputStream é usado para ler dados de uma fonte.

  • OutPutStream - O OutputStream é usado para gravar dados em um destino.

Java fornece suporte forte, mas flexível, para E / S relacionada a arquivos e redes, mas este tutorial cobre a funcionalidade muito básica relacionada a fluxos e E / S. Veremos os exemplos mais comumente usados, um por um -

Streams de bytes

Os fluxos de bytes Java são usados ​​para realizar a entrada e saída de bytes de 8 bits. Embora existam muitas classes relacionadas a fluxos de bytes, mas as classes mais usadas são,FileInputStream e FileOutputStream. A seguir está um exemplo que faz uso dessas duas classes para copiar um arquivo de entrada em um arquivo de saída -

Example

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {  
      FileInputStream in = null;
      FileOutputStream out = null;

      try {
         in = new FileInputStream("input.txt");
         out = new FileOutputStream("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

Agora vamos ter um arquivo input.txt com o seguinte conteúdo -

This is test for copy file.

Como próximo passo, compile o programa acima e execute-o, o que resultará na criação do arquivo output.txt com o mesmo conteúdo que temos em input.txt. Então, vamos colocar o código acima no arquivo CopyFile.java e fazer o seguinte -

$javac CopyFile.java
$java CopyFile

Streams de personagens

Java Byte streams são usados ​​para realizar entrada e saída de bytes de 8 bits, enquanto Java Characterstreams são usados ​​para realizar entrada e saída para Unicode de 16 bits. Embora existam muitas classes relacionadas a fluxos de caracteres, as classes mais usadas são,FileReader e FileWriter. Embora internamente o FileReader use FileInputStream e FileWriter use FileOutputStream, a principal diferença é que o FileReader lê dois bytes por vez e o FileWriter grava dois bytes por vez.

Podemos reescrever o exemplo acima, que faz o uso dessas duas classes para copiar um arquivo de entrada (com caracteres Unicode) para um arquivo de saída -

Example

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {
      FileReader in = null;
      FileWriter out = null;

      try {
         in = new FileReader("input.txt");
         out = new FileWriter("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

Agora vamos ter um arquivo input.txt com o seguinte conteúdo -

This is test for copy file.

Como próximo passo, compile o programa acima e execute-o, o que resultará na criação do arquivo output.txt com o mesmo conteúdo que temos em input.txt. Então, vamos colocar o código acima no arquivo CopyFile.java e fazer o seguinte -

$javac CopyFile.java
$java CopyFile

Streams padrão

Todas as linguagens de programação fornecem suporte para E / S padrão, onde o programa do usuário pode obter a entrada de um teclado e, em seguida, produzir uma saída na tela do computador. Se você conhece as linguagens de programação C ou C ++, deve conhecer os três dispositivos padrão STDIN, STDOUT e STDERR. Da mesma forma, o Java fornece os três fluxos padrão a seguir -

  • Standard Input - Isso é usado para alimentar os dados para o programa do usuário e geralmente um teclado é usado como fluxo de entrada padrão e representado como System.in.

  • Standard Output - Isso é usado para produzir os dados produzidos pelo programa do usuário e geralmente uma tela de computador é usada para fluxo de saída padrão e representada como System.out.

  • Standard Error - Isso é usado para produzir os dados de erro produzidos pelo programa do usuário e geralmente uma tela de computador é usada para o fluxo de erro padrão e representada como System.err.

A seguir está um programa simples, que cria InputStreamReader para ler o fluxo de entrada padrão até que o usuário digite um "q" -

Example

import java.io.*;
public class ReadConsole {

   public static void main(String args[]) throws IOException {
      InputStreamReader cin = null;

      try {
         cin = new InputStreamReader(System.in);
         System.out.println("Enter characters, 'q' to quit.");
         char c;
         do {
            c = (char) cin.read();
            System.out.print(c);
         } while(c != 'q');
      }finally {
         if (cin != null) {
            cin.close();
         }
      }
   }
}

Vamos manter o código acima no arquivo ReadConsole.java e tentar compilá-lo e executá-lo conforme mostrado no programa a seguir. Este programa continua a ler e produzir o mesmo caractere até que pressione 'q' -

$javac ReadConsole.java
$java ReadConsole
Enter characters, 'q' to quit.
1
1
e
e
q
q

Ler e escrever arquivos

Conforme descrito anteriormente, um fluxo pode ser definido como uma sequência de dados. oInputStream é usado para ler dados de uma fonte e o OutputStream é usado para gravar dados em um destino.

Aqui está uma hierarquia de classes para lidar com fluxos de entrada e saída.

Os dois fluxos importantes são FileInputStream e FileOutputStream, que será discutido neste tutorial.

FileInputStream

Este fluxo é usado para ler dados dos arquivos. Os objetos podem ser criados usando a palavra-chavenew e existem vários tipos de construtores disponíveis.

O construtor a seguir leva um nome de arquivo como uma string para criar um objeto de fluxo de entrada para ler o arquivo -

InputStream f = new FileInputStream("C:/java/hello");

O construtor a seguir usa um objeto de arquivo para criar um objeto de fluxo de entrada para ler o arquivo. Primeiro, criamos um objeto de arquivo usando o método File () da seguinte maneira -

File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);

Depois de ter o objeto InputStream em mãos, há uma lista de métodos auxiliares que podem ser usados ​​para ler o fluxo ou fazer outras operações no fluxo.

Sr. Não. Método e Descrição
1

public void close() throws IOException{}

Este método fecha o fluxo de saída do arquivo. Libera todos os recursos do sistema associados ao arquivo. Lança uma IOException.

2

protected void finalize()throws IOException {}

Este método limpa a conexão com o arquivo. Garante que o método close deste fluxo de saída de arquivo seja chamado quando não houver mais referências a este fluxo. Lança uma IOException.

3

public int read(int r)throws IOException{}

Este método lê o byte de dados especificado do InputStream. Retorna um int. Retorna o próximo byte de dados e -1 será retornado se for o fim do arquivo.

4

public int read(byte[] r) throws IOException{}

Este método lê bytes r.length do fluxo de entrada em uma matriz. Retorna o número total de bytes lidos. Se for o fim do arquivo, -1 será retornado.

5

public int available() throws IOException{}

Fornece o número de bytes que podem ser lidos desse fluxo de entrada de arquivo. Retorna um int.

Existem outros fluxos de entrada importantes disponíveis, para mais detalhes, você pode consultar os seguintes links -

FileOutputStream

FileOutputStream é usado para criar um arquivo e gravar dados nele. O fluxo criaria um arquivo, se ainda não existir, antes de abri-lo para saída.

Aqui estão dois construtores que podem ser usados ​​para criar um objeto FileOutputStream.

O construtor a seguir usa um nome de arquivo como uma string para criar um objeto de fluxo de entrada para escrever o arquivo -

OutputStream f = new FileOutputStream("C:/java/hello")

O construtor a seguir pega um objeto de arquivo para criar um objeto de fluxo de saída para gravar o arquivo. Primeiro, criamos um objeto de arquivo usando o método File () da seguinte maneira -

File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

Depois de ter o objeto OutputStream em mãos, há uma lista de métodos auxiliares, que podem ser usados ​​para escrever em um fluxo ou para fazer outras operações no fluxo.

Sr. Não. Método e Descrição
1

public void close() throws IOException{}

Este método fecha o fluxo de saída do arquivo. Libera todos os recursos do sistema associados ao arquivo. Lança uma IOException.

2

protected void finalize()throws IOException {}

Este método limpa a conexão com o arquivo. Garante que o método close deste fluxo de saída de arquivo seja chamado quando não houver mais referências a este fluxo. Lança uma IOException.

3

public void write(int w)throws IOException{}

Este método grava o byte especificado no fluxo de saída.

4

public void write(byte[] w)

Grava bytes w.length da matriz de bytes mencionada no OutputStream.

Existem outros fluxos de saída importantes disponíveis; para mais detalhes, você pode consultar os seguintes links -

Example

A seguir está o exemplo para demonstrar InputStream e OutputStream -

import java.io.*;
public class fileStreamTest {

   public static void main(String args[]) {
   
      try {
         byte bWrite [] = {11,21,3,40,5};
         OutputStream os = new FileOutputStream("test.txt");
         for(int x = 0; x < bWrite.length ; x++) {
            os.write( bWrite[x] );   // writes the bytes
         }
         os.close();
     
         InputStream is = new FileInputStream("test.txt");
         int size = is.available();

         for(int i = 0; i < size; i++) {
            System.out.print((char)is.read() + "  ");
         }
         is.close();
      } catch (IOException e) {
         System.out.print("Exception");
      }	
   }
}

O código acima criaria o arquivo test.txt e escreveria os números dados em formato binário. O mesmo seria a saída na tela stdout.

Navegação em arquivos e I / O

Existem várias outras classes pelas quais passaríamos para conhecer os fundamentos de Navegação de Arquivos e E / S.

Diretórios em Java

Um diretório é um arquivo que pode conter uma lista de outros arquivos e diretórios. Você usaFileobjeto para criar diretórios, para listar os arquivos disponíveis em um diretório. Para detalhes completos, verifique uma lista de todos os métodos que você pode chamar no objeto File e quais estão relacionados aos diretórios.

Criação de diretórios

Existem dois úteis File métodos utilitários, que podem ser usados ​​para criar diretórios -

  • o mkdir( )método cria um diretório, retornando true em caso de sucesso e false em caso de falha. Falha indica que o caminho especificado no objeto Arquivo já existe ou que o diretório não pode ser criado porque o caminho inteiro ainda não existe.

  • o mkdirs() método cria um diretório e todos os pais do diretório.

O exemplo a seguir cria o diretório "/ tmp / user / java / bin" -

Example

import java.io.File;
public class CreateDir {

   public static void main(String args[]) {
      String dirname = "/tmp/user/java/bin";
      File d = new File(dirname);
      
      // Create directory now.
      d.mkdirs();
   }
}

Compile e execute o código acima para criar "/ tmp / user / java / bin".

Note- Java cuida automaticamente dos separadores de caminho no UNIX e Windows de acordo com as convenções. Se você usar uma barra (/) em uma versão Windows do Java, o caminho ainda será resolvido corretamente.

Listagem de diretórios

Você pode usar list( ) método fornecido por File objeto para listar todos os arquivos e diretórios disponíveis em um diretório da seguinte forma -

Example

import java.io.File;
public class ReadDir {

   public static void main(String[] args) {
      File file = null;
      String[] paths;
  
      try {      
         // create new file object
         file = new File("/tmp");

         // array of files and directory
         paths = file.list();

         // for each name in the path array
         for(String path:paths) {
            // prints filename and directory name
            System.out.println(path);
         }
      } catch (Exception e) {
         // if any error occurs
         e.printStackTrace();
      }
   }
}

Isso produzirá o seguinte resultado com base nos diretórios e arquivos disponíveis em seu /tmp diretório -

Output

test1.txt
test2.txt
ReadDir.java
ReadDir.class