Aprendendo a Manipular Arquivos Em Java

7
Aprendendo a manipular arquivos Guilherme Silveira Que escrever e ler em arquivos? Este tutorial mostra o básico das operações d escrita em arquivos, assim como outras simples operações. Introdução Uma das principais facilidades em ava, comparando com outras lin!ua! pro!ramaç"o, # a facilidade na leitura e !ravaç"o de arquivos no sist operacional sem ter de se preocupar com o sistema operacional no qual aplicaç"o está rodando. Sendo ava uma lin!ua!em orientada a ob$etos, nada mais claro que uti classes e inst&ncias delas 'ob$etos( para lidar com a saida e entrada 'input)output, abreviado* io(. + $ava trata a entrada e sa da como fl 'os t"o chamados Streams(, que voc tem pleno controle sobre eles. /l#m disso, a abstraç"o criada pela lin!ua!em sobre os Streams # t"o muitas ve%es voc está pu-ando)escrevendo dados em al!um Stream, e vo sabe se eles est"o vindo da internet, de um arquivo te-to, ou do usuá di!itando no console. E o mais importante* n"o fa% a menor diferença infromaç"o0 /s classes li!adas a io est"o nos pacotes java.io e java.nio '1E2 io( ensinando o básico das classes responsáveis pela leitura e !ravaç"o d modo n"o binário, isto #, tratando com Strin!s e caracteres. Este tut passo a passo o que acontece no c3di!o, para que voc entenda perfeit que # feito, e n"o decore simplesmente o c3di!o. 4nst&ncias da classe java.io.File representam caminhos 'paths( para p locais no sistema operacional. 5embre6se que ele apenas representa um

description

Manipulação de arquivos com Java.

Transcript of Aprendendo a Manipular Arquivos Em Java

Aprendendo a manipular arquivos

Aprendendo a manipular arquivos

Guilherme Silveira

Que escrever e ler em arquivos? Este tutorial mostra o bsico das operaes de leitura e escrita em arquivos, assim como outras simples operaes.

Introduo

Uma das principais facilidades em Java, comparando com outras linguages de programao, a facilidade na leitura e gravao de arquivos no sistema operacional sem ter de se preocupar com o sistema operacional no qual sua aplicao est rodando.

Sendo Java uma linguagem orientada a objetos, nada mais claro que utilizar classes e instncias delas (objetos) para lidar com a saida e entrada de dados (input/output, abreviado: io). O java trata a entrada e sada como fluxos de dados (os to chamados Streams), que voc tem pleno controle sobre eles.

Alm disso, a abstrao criada pela linguagem sobre os Streams to grande, que muitas vezes voc est puxando/escrevendo dados em algum Stream, e voc no sabe se eles esto vindo da internet, de um arquivo texto, ou do usurio que est digitando no console. E o mais importante: no faz a menor diferena esta infromao!

As classes ligadas a io esto nos pacotes java.io e java.nio (NEW io) e estarei ensinando o bsico das classes responsveis pela leitura e gravao de arquivos de modo no binrio, isto , tratando com Strings e caracteres. Este tutorial explicar passo a passo o que acontece no cdigo, para que voc entenda perfeitamente o que feito, e no decore simplesmente o cdigo.

Instncias da classe java.io.File representam caminhos (paths) para possveis locais no sistema operacional. Lembre-se que ele apenas representa um arquivo ou diretrio, isto no quer dizer que este caminho exista ou no.

Por exemplo, o cdigo a seguir cria uma instncia da classe mencionada, que aponta para /usr/guj/arquivo.txt:

1Filefile=newFile("/usr/guj/arquivo.txt");

E o cdigo a seguir um caminho para o arquivo arquivo.txt que estara no diretrio atual do sistema e ../arquivo.txt que estar no diretrio pai do atual.

Dica: No caso do sistema operacional windows, voc deve usar duplas barras invertidas (\\), j que uma barra invertida apenas considerado escape pelo java!

Dica: Em java, voce NO tem como alterar o diretrio atual, por isso pode criar instncias da classe File que apontam para lugares relativos, mas sempre ao diretrio inicial, veja o segundo exemplo abaixo:

1FilenoDiretorioAtual=newFile("arquivo.txt");2FilenoDiretorioAnterior=newFile("../arquivo.txt");

Existe outras maneiras de criar caminhos relativos a um outro caminho, por exemplo:

1FilediretorioRaiz=newFile("/");2Filearquivo1=newFile(diretorioRaiz,"autoexec.bat");3Filearquivo2=newFile(diretorioRaiz,"config.sys");4FilediretorioWindows=newFile(diretorioRaiz,"windows");5FilediretorioWindows2=newFile("/windows/");6FilediretorioWindows3=newFile("/windows");7FilediretorioWindows4=newFile("c:\\\\windows");

Dica: importante saber que criar um ponteiro para um caminho no sistema operacional no significa criar o arquivo/diretrio. As instanciaes do cdigo acima iriam funcionar mesmo se voc no possuisse esses arquivos, porm no iro apontar para um arquivo/diretrio existente.

Vamos mostrar um pouco mais da API desta classe, para que voc saiba o que tem disponvel.

O primeiro passo descobrir se uma instncia da classe java.io.File aponta para algo que existe, para um diretrio ou arquivo.

Os trs mtodos teis nesse momento so:

1booleanexists();2booleanisDirectory();3booleanisFile();

Outros mtodos que podem ser teis para checar a viabilidade de leitura e grava sao:

1booleancanRead();2booleancanWrite();

E por fim, alguns mtodos de criao de diretrios, sendo o primeiro o que cria um diretrio e o segundo cria todos os diretrios necessarios para chegar no caminho apontado pelo objeto. Esses costumam ser muito utilizados:

1booleanmkdir();2booleanmkdirs();

E outros mtodos comuns so:

1booleanrenameTo(Filefile);2longlength();3longlastModified();4booleandelete();

Todos os nomes so auto explicativos. Qualquer coisa, consulte a API da classe File, j que esta ser sua eterna companheira. Alguma pessoas criticam muito essa classe, pois ela deixa voc instanci-la mesmo que ela no represente um arquivo realmente, o que no acontece com as classes a seguir.

Nesse tutorial no discutiremos sobre arquivos que contm todo o leque de caracteres Unicode e sim arquivos ASCII-8, portanto, aqueles que procuram esse tipo de informao, podem dar uma olhada nas classes java.io.FileOutputStream e java.io.OutputStreamWriter que iro criar um Writer para ser encapsulado pelo PrintWriter.

Para escrever (e ler de) em um arquivo precisamos saber que Java tem duas camadas de io. Um baixo que le e escreve bytes e um alto que escreve e le caracteres. Vamos estudar os de alto nvel, juntamente com algum encapsulando por cima deste, pois o de alto nvel mexe com chars, e o que encapsula mexe com tudo!

O rescritor de caracteres que iremos usar ser uma instncia da classe java.io.FileWriter:

1FileWriterwriter=newFileWriter(newFile("saida.txt"),true);2FileWriterwriter=newFileWriter(newFile("saida.txt"));3FileWriterwriter=newFileWriter("saida.txt",true);4FileWriterwriter=newFileWriter("saida.txt");

Repare que as duas primeiras linhas obtm o mesmo resultado que a terceira e a quarta, pois existem construtores para objetos do tipo File e String.

Dica: Se voc especificar um segundo parametro 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 instncia do "gravador" de caracteres, mas desejamos escrever Strings para o arquivo utilizando uma instancia da classe java.io.PrintWriter que fornece as funcoes print() e println(0.

1PrintWritersaida=newPrintWriter(writer);2PrintWritersaida=newPrintWriter(writer,true);

Dica: especificando o segundo parametro como true, os dados sero enviados para o arquivo a toda chamada do mtodo println(), caso contrrio, os dados s so enviados quando voce enviar uma quebra de linha, fechar o arquivo ou mandar ele atualizar as mudanas (modo autoflush).

Repare que voc utiliza um objeto da classe java.io.PrintWriter sempre! o System.out uma instncia desta classe, obviamente encapsulando uma outra Stream.

Agora voc j pode escrever no arquivo que abriu:

1saida.println("Camera'sready,");2saida.println("Preparetoflash....");3saida.println("GreenVelvet");

Por fim, voce deve fechar o arquivo na ordem contrria que abriu, por segurana:

1saida.close();2writer.close();

Dica: Nunca se esquea de fechar esses objetos, que liberam recursos para o sistema. Esperar pelo Garbage Collector pode ser a diferena da sua aplicao rodar rpido ou no!

Assim como sobre a escrita, voc deve dar uma lida na API das classes java.io.FileInputStream e java.io.InputStreamWriter para utilizar de mtodos compatveis com caracteres UNICODE.

O leito de caracteres que iremos usar durante a leitur sera uma instncia da classe java.io.FileReader:

1FileReaderreader=newFileReader(newFile("saida.txt"));2FileReaderreader=newFileReader("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.

1BufferedReaderleitor=newBufferedReader(reader);2BufferedReaderleitor=newBufferedReader(reader,1*1024*1024);

Dica: voce pode especificar o tamanho do buffer desejado no segundo parmetro. Esse buffer utilizado para minimizar o nmero de pedidos de io para ler blocos maiores do arquivo de uma vez s. Aumentando esse nmero diminui os acessos a disco, mas aumenta o consumo de memria!

Agora voc j pode ler:

1Stringlinha=null;2while((linha=leitor.readLine())){3System.out.println("Linha:"+linha);4}

E no se esquea de fechar os dois objetos:

1leitor.close();2reader.close();

Voc pode utilizar a classe BufferedWriter para agilizar tambm o processo de gravao:

1PrintWriterout=newPrintWriter(newBufferedWriter(newFileWriter("saida.txt")));2PrintWriterout=newPrintWriter(newBufferedWriter(newFileWriter("saida.txt"),1*1024*1024));

Caso voce no utilize um objeto BufferedWriter no meio, voce ter como resultado uma converso de caracteres em bytes e gravao no arquivo a cada chamada do mtodo print e suas variantes, o que pode ser MUITO custoso.

Agora voc j consegue ler e gravar arquivos, inclusive otimizando as respectivas operaes.

Os prximos passo podem ser:

aprender a gravar e ler objetos de um arquivo utilizando as classes ObjectInputStream e ObjectOutputStream,

acessar um arquivo de modo aleatrio para leitura e grava usando a classe RandomAccessFile,

parsear a Stream usando (a super lenta) StreamTokenizer,

ler e gravar em variaveis em vez de arquivos usando StringReader e StringWriter,

utilizar caracteres UNICODE especificando a codificacao ao instanciar objetos do tipo InputStreamReader e InputStreamWriter.

De exerccio, fica ler um arquivo e gravar uma cpia dele alterando todas as aparies de uma determinada String em uma outra, da maneira mais eficiente possvel!