A entrada e saída (Input/Output) em Java é um conceito essencial ao se trabalhar com Java. Ele consiste em elementos como entrada, saída e fluxo.
A entrada são os dados que damos ao programa. A saída são os dados que recebemos do programa na forma de resultado.
Stream representa o fluxo de dados ou a sequência de dados. Para dar entrada, usamos o fluxo de entrada e para dar saída, usamos o fluxo de saída.
Com o Java, a tarefa de leitura e gravação de arquivos é facilitada em comparação com outras linguagens de programação.
Por ser uma linguagem orientada a objetos, é aconselhável a utilização de classes e objetos para manipular a entrada e saída de dados (INPUT/OUTPUT).
A linguagem Java trata a entrada e saída como fluxos de dados (streams).
java.io.File
Instâncias da classe java.io.File representam caminhos (paths) para possíveis locais no sistema operacional. Lembre-se que ele apenas representa um arquivo ou diretório.
Por exemplo, o código a seguir cria uma instância da classe mencionada, que aponta para /usr/guj/arquivo.txt:
File file = new File("/usr/guj/arquivo.txt");
E o código a seguir um caminho para o arquivo arquivo.txt que estará no diretório atual do sistema e ../arquivo.txt que estará no diretório pai do atual.
No caso do sistema operacional windows, você deve usar duplas barras invertidas (\\), já que uma barra invertida apenas é considerado escape pelo java.
Em java, você não tem como alterar o diretório atual, por isso pode criar instâncias da classe File que apontam para lugares relativos, mas sempre ao diretório inicial, veja o exemplo abaixo:
File noDiretorioAtual = new File("arquivo.txt");
File noDiretorioAnterior = new File("../arquivo.txt");
Existe outras maneiras de criar caminhos relativos a um outro caminho, por exemplo:
File diretorioRaiz = new File("/");
File arquivo1 = new File(diretorioRaiz,"autoexec.bat");
File arquivo2 = new File(diretorioRaiz,"config.sys");
File diretorioWindows = new File(diretorioRaiz,"windows");
File diretorioWindows2 = new File("/windows/");
File diretorioWindows3 = new File("/windows");
File diretorioWindows4 = new File("c:\\windows");
É importante saber que criar um ponteiro para um caminho no sistema operacional não significa criar o arquivo/diretório.
As instanciações do código acima iriam funcionar mesmo se você não possuisse esses arquivos, porém não irão apontar para um arquivo/diretório existente.
Um pouco mais da API da classe java.io.File
Vamos mostrar um pouco mais da API desta classe, para que você saiba o que tem disponível. O primeiro passo é descobrir se uma instância da classe java.io.File aponta para algo que existe, para um diretório ou arquivo. Os três métodos úteis nesse momento são:
boolean exists();
boolean isDirectory();
boolean isFile();
Outros métodos que podem ser úteis para checar a viabilidade de leitura e gravaçã sao:
boolean canRead();
boolean canWrite();
E por fim, alguns métodos de criação de diretórios, sendo o primeiro o que cria um diretório e o segundo cria todos os diretórios necessarios para chegar no caminho apontado pelo objeto. Esses costumam ser muito utilizados:
boolean mkdir();
boolean mkdirs();
E outros métodos comuns são:
boolean mkdir();
boolean mkdirs();
O Java tem duas camadas de IO. Um baixo, que lê e escreve bytes, e um alto, que escreve e le caracteres.
Vamos ver os de alto nível, juntamente com algum encapsulando por cima deste, pois o de alto nível mexe com chars, e o que encapsula mexe com tudo.
O rescritor de caracteres que iremos usar será uma instância da classe java.io.FileWriter:
FileWriter writer = new FileWriter(new File("saida.txt"),true);
FileWriter writer = new FileWriter(new File("saida.txt"));
FileWriter writer = new FileWriter("saida.txt",true);
FileWriter writer = new FileWriter("saida.txt");
As duas primeiras linhas obtém o mesmo resultado que a terceira e a quarta, pois existem construtores para objetos do tipo File e String.
Se você especificar um segundo parâmetro como true (primeira e terceira linha), você pode dizer que deseja adicionar dados a um arquivo que ja existe em vez de sobregravar esse arquivo (modo append).
Agora já temos uma instância do “gravador” de caracteres, mas desejamos escrever Strings para o arquivo utilizando uma instância da classe java.io.PrintWriter que fornece as funcoes print() e println(0).
PrintWriter saida = new PrintWriter(writer);
PrintWriter saida = new PrintWriter(writer,true);
Especificando o segundo parâmetro como true, os dados serão enviados para o arquivo a toda chamada do método println(), caso contrário, os dados só são enviados quando você enviar uma quebra de linha, fechar o arquivo ou mandar ele atualizar as mudanças (modo autoflush).
Repare que você utiliza um objeto da classe java.io.PrintWriter, o System.out é uma instância desta classe, obviamente encapsulando uma outra Stream. Agora você já pode escrever no arquivo que abriu:
saida.println("Tenho dinheiro,");
saida.println("saúde, ");
saida.println("e muita paz!");
Agora você deve fechar o arquivo na ordem contrária que abriu, por segurança:
saida.close();
writer.close();
Sempre feche esses objetos, que liberam recursos para o sistema. Não confie no Garbage Collector!
java.io.FileReader e java.io.BufferedReader
Assim como sobre a escrita, você deve conhecer o API das classes java.io.FileInputStream e java.io.InputStreamWriter para utilizar de métodos compatíveis com caracteres UNICODE.
O leito de caracteres que iremos usar durante a leiturá sera uma instância da classe java.io.FileReader:
FileReader reader = new FileReader(new File("saida.txt"));
FileReader reader = new FileReader("saida.txt");
Como no exemplo de escrita, as duas linhas acima possuem o mesmo resultado.
Agora, instanciamos um objeto da classe java.io.BufferedReader que fornece a funcao readLine() e algumas outras, para agilizar o trabalho.
BufferedReader leitor = new BufferedReader(reader);
BufferedReader leitor = new BufferedReader(reader,1*1024*1024);
Você pode especificar o tamanho do buffer desejado no segundo parâmetro.
Esse buffer é utilizado para minimizar o número de pedidos de io para ler blocos maiores do arquivo de uma vez só. Aumentando esse número diminui os acessos a disco, mas aumenta o consumo de memória! Agora você já pode ler:
String linha = null;
while((linha = leitor.readLine())) {
System.out.println("Linha: " + linha);
}
Não se esqueça de fechar os dois objetos:
leitor.close();
reader.close();
java.io.BufferedWriter
Você pode utilizar a classe BufferedWriter para agilizar também o processo de gravação:
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("saida.txt")));
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("saida.txt"),
1*1024*1024));
Caso você não utilize um objeto BufferedWriter no meio, voce terá como resultado uma conversão de caracteres em bytes e gravação no arquivo a cada chamada do método print e suas variantes, o que pode ser muito custoso.
Domine as boas práticas com projetos práticos que vão te ajudar a desenvolver sistemas e se destacar no mercado de programação.
Clique na imagem abaixo e conheça mais detalhes do nosso curso:
Dúvidas ou sugestões? Deixem nos comentários! Para mais dicas, acesse o nosso canal no YouTube:
https://youtube.com/criandobits
Quer receber GRÁTIS o e-book "Como Formatar um Computador em 5 Minutos"?
Sobre o Autor
0 Comentários