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.
Transmissão
Um fluxo pode ser definido como uma sequência de dados. Existem dois tipos de fluxos -
-
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 relacionadas a arquivos e redes, mas este tutorial abrange funcionalidades muito básicas relacionadas a fluxos e E/S. Veremos os exemplos mais usados um por um -
Fluxos de bytes
Os fluxos de bytes Java são usados para executar 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 -
Exemplo
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 no input.txt. Então vamos colocar o código acima no arquivo CopyFile.java e fazer o seguinte −
$javac CopyFile.java $java CopyFile
Fluxos de personagens
Java Byte streams são usados para realizar entrada e saída de bytes de 8 bits, enquanto Java Character fluxos são usados para executar entrada e saída para unicode de 16 bits. Embora existam muitas classes relacionadas a fluxos de caracteres, mas as classes mais usadas são, FileReader e FileWriter . Embora internamente o FileReader use o FileInputStream e o FileWriter use o FileOutputStream, aqui 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) em um arquivo de saída −
Exemplo
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 no 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 receber entradas de um teclado e então produzir uma saída na tela do computador. Se você conhece C ou C++ linguagens de programação, então você deve estar ciente de três dispositivos padrão STDIN, STDOUT e STDERR. Da mesma forma, Java fornece os três fluxos padrão a seguir -
-
Entrada padrão − 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 .
-
Saída padrão − 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 .
-
Erro padrão − Isso é usado para gerar os dados de erro produzidos pelo programa do usuário e geralmente uma tela de computador é usada para 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" -
Exemplo
Demonstração ao vivo
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é pressionarmos 'q' -
$javac ReadConsole.java $java ReadConsole Enter characters, 'q' to quit. 1 1 e e q q
Ler e gravar arquivos
Conforme descrito anteriormente, um fluxo pode ser definido como uma sequência de dados. O InputStream é 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-chave new e existem vários tipos de construtores disponíveis.
O construtor a seguir recebe 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 InputStream objeto 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.
Nº Sr. | Método e descrição |
---|---|
1 | public void close() lança 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() lança IOException {} Este método limpa a conexão com o arquivo. Garante que o método close desse fluxo de saída de arquivo seja chamado quando não houver mais referências a esse fluxo. Lança uma IOException. |
3 | public int read(int r) lança 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 final do arquivo. |
4 | public int read(byte[] r) lança 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 final do arquivo, -1 será retornado. |
5 | public int available() lança 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 −
-
ByteArrayInputStream
-
DataInputStream
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 recebe um nome de arquivo como uma string para criar um objeto de fluxo de entrada para gravar o arquivo -
OutputStream f = new FileOutputStream("C:/java/hello")
O construtor a seguir usa 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 OutputStream objeto em mãos, há uma lista de métodos auxiliares, que podem ser usados para gravar no fluxo ou para fazer outras operações no fluxo.
Nº Sr. | Método e descrição |
---|---|
1 | public void close() lança 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() lança IOException {} Este método limpa a conexão com o arquivo. Garante que o método close desse fluxo de saída de arquivo seja chamado quando não houver mais referências a esse fluxo. Lança uma IOException. |
3 | public void write(int w) lança 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 −
-
ByteArrayOutputStream
-
DataOutputStream
Exemplo
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 determinados números em formato binário. O mesmo seria a saída na tela stdout.
Navegação de arquivos e E/S
Existem várias outras classes pelas quais passaríamos para conhecer os conceitos básicos de Navegação de Arquivos e E/S.
-
Classe de arquivo
-
Classe FileReader
-
Classe FileWriter
Diretórios em Java
Um diretório é um arquivo que pode conter uma lista de outros arquivos e diretórios. Você usa Arquivo objeto 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.
Criando diretórios
Existem dois Arquivos úteis métodos utilitários, que podem ser usados para criar diretórios -
-
O mkdir() O método cria um diretório, retornando true em caso de sucesso e false em caso de falha. A 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.
-
Os mkdirs() O 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" -
Exemplo
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".
Observação − 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.
Diretórios de listagem
Você pode usar lista( ) método fornecido por Arquivo object para listar todos os arquivos e diretórios disponíveis em um diretório da seguinte forma -
Exemplo
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 -
Saída
test1.txt test2.txt ReadDir.java ReadDir.class
Java