CriandoBits
Identifique-se Entrar Esqueceu a senha? Esqueci minha senha

Java - Input/Output

Por Benedito Silva Júnior - publicado em 18/07/2016


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. 

 
Voltar a pagina anteriorVoltarSubir ao topo da páginaTopo