Professional Documents
Culture Documents
Confuso com a profuso de classes e mtodos disponveis na plataforma .NET para ler e escrever em arquivos? Afinal
quando vou acessar para ler ou escrever em um arquivo qual classe devo usar? Como fao para arquivos textos?
Antes de irmos direto para a parte prtica, vamos tentar ter uma viso geral da hierarquia de classes que a
plataforma .NET oferece para esta finalidade.
Um pouco de teoria
As operaes de input e output na plataforma .NET so gerenciadas pela classe abstrata Stream, que est no
namespace System.IO. Se voc conhece os fundamentos da programao orientada a objetos deve saber que uma
classe abstrata no pode ser instanciada diretamente. Portanto voc no pode usar a classe Stream diretamente
para acessar arquivos.
Ento para que serve esta classe? Serve para padronizar e fornecer um contrato com mtodos e propriedades que
devem ser implementadas por outras classes que herdam da classe Stream. Notou a palavra mgica herana? Pois
bem, a plataforma .NET oferece uma hierarquia de classes que podemos usar para realizar operaes
de input/output.(I/O).
A seguir vemos uma figura que mostra resumidamente a hierarquia de classes que herdam da classe Stream:
Podemos dizer que a classe Stream a raiz das classes que tratam um fluxo de dados ou stream. Como vemos
existem muitas classes que derivam a classe Stream e podemos dividi-las em duas categorias:
A primeira categoria contm todas as classes que implementam a classe Stream para uma operao especfica de
I/O. Essas classes so:
FileStream, para trabalhar com arquivos;
NetworkStream, para transferncia de dados em rede;
MemoryStream, para a troca de dados em memria.
A segunda categoria contm classes derivadas de Stream que reforam o que a classe Stream tem a oferecer. Elas
podem ser considerados como uma camada sobre a funcionalidade bsica oferecida pela classe Stream.
Esta categoria inclui os seguintes classes:
BufferedStream, que permitem realizar a operao tamponada sobre um stream. Devido ao fato que os dados no
so gravados diretamente para o stream, o nmero de operaes I/O necessrios para executar a operao menor,
aumentando assim, a execuo da operao;
CryptoStream, que permitem que os dados escritos ou lidos a partir do fluxo de dados possa ser criptografado ou
descriptografado.
Como todas as classes que tratam streams ou fluxo de dados herdam da classe Stream, vejamos a seguir os mtodos
e propriedades desta classe que as demais classes tem que implementar:
1. Propriedades
CanRead
CanSeek
CanTimeout
CanWrite
Length
Position
ReadTimeout
Obtm ou define um valor, em milisegundos, que determina quanto tempo o fluxo tentar ler antes
do time out.
WriteTimeout
Obtm ou define um valor, em milisegundos, que determina quanto tempo o fluxo tentar escrever
antes do time out.
BeginWrite
Close
CopyTo(Stream)
Dispose()
EndRead
EndWrite
Equals(Object)
Finalize
Permite que um objeto tente liberar recursos e executar outras operaes de limpeza antes que
ele seja recuperado pela coleta de lixo. (Herdado de Object.)
Flush
Limpa todos os buffers para esse fluxo e faz com que alguns dados armazenados em buffer
sejam gravados no dispositivo subjacente.
Read
L uma sequncia de bytes de fluxo atual e avana a posio no fluxo pelo nmero de bytes
lidos.
Seek
SetLength
ToString
Write
Grava uma sequncia de bytes no fluxo atual e avana a posio atual dentro desse fluxo pelo
nmero de bytes escritos.
Ento, para ler e escrever em arquivos textos podemos use as classes StreamReader/StreamWriter. Essas classes
derivam das classes TextReader/TextWriter.
Abaixo temos uma figura onde temos as classes do namespace System.IO mostrando a hierarquia de herana das
principais classes para Input/OutPut:
As classes TextReader/TextWriter representam um leitor/escritor que podem ler/escrever uma srie sequencial de
caracteres. Elas so classes abstratas e no podem ser instanciadas diretamente.
Observe que as classes StreamReader/StreamWriter herdam de TextReader e de TextWriter. Conclumos, assim,
que StreamReader um tipo de TextReader e que StreamWriter um tipo de TextWriter. Assim,
um StreamReader obtm os seus dados de um fluxo ou stream que pode se representado por dados que esto na
memria, em um arquivo ou vindo de uma porta serial, vdeo ou capturado em um dispositivo. Dessa forma,
um StreamReader possui uma implementao especfica para leitura de caracteres de um stream como um arquivo.
StreamReader implementa um TextReader que l caracteres de um fluxo de bytes em uma codificao especfica.
TextReader representa um leitor que pode ler uma srie seqencial de caracteres.(classe abstrata).
Concluso: se eu preciso de uma rotina para ler e/ou escrever em arquivos texto, eu vou usar
um StreamReader/StreamWriter.
Escrevendo e lendo arquivos textos
Vamos comear mostrando como criar e escrever em arquivos texto usando StreamWriter.
A seguir, as principais propriedades e mtodos da classe StreamWriter:
Obtm ou define um valor indicando
se o StreamWriter ir liberar o buffer
AutoFlush()
no fluxo subjacente aps cada
chamada aWrite.
Close()
Dispose()
Flush()
NewLine()
Write()
Grava no fluxo.
WriteLine()
Para comear, temos que referenciar o namespace System.IO e declarar e inicializar uma nova instncia
de StreamWriter usando um de seus construtores.
StreamWriter writer = new StreamWriter(macoratti.txt)
Nesta declarao, um novo StreamWriter inicializado com o nome do arquivo igual macoratti.txt (voc pode usar
qualquer extenso como .dat, por exemplo).
Se o arquivo no existir, ela ser criado. No exemplo, como no definimos um local para o arquivo, ele ser criado no
mesmo diretrio da aplicao.
Para escrever no arquivo podemos usar o mtodo Write() ou WriteLine(). Estes mtodos possuem diversas
sobrecargas.
1
writer.WriteLine("http://www.macoratti.net");
No cdigo, o mtodo Write() escreve uma linha e no anexa uma linha. J o mtodo WriteLine() anexa uma nova
linha (\r\n) ao arquivo a cada chamada. Observe que estamos usando a clusula using de forma a liberar os
recursos usados na operao aps sua utilizao. Nunca esquea de liberar os recursos usados e tambm verifique
sempre se o arquivo existe quando necessrio.
Se desejarmos escrever em um arquivo j existente anexando linhas ao arquivo podemos usar o construtor
: StreamWriter(string caminho, bool anexa).
Inicialize uma nova instncia do StreamWriter para o arquivo no caminho especificado, usando a codificao padro
e buffer. Se o arquivo existir, pode ser tanto sobrescrito ou anexado. Se o arquivo no existir, este construtor cria um
novo arquivo.
1
using System.IO;
class Program
10
writer.WriteLine("Macoratti .net");
11
12
13
14
15
16
17
18
No cdigo acima inicia com um novo StreamWriter e abre o arquivo c:\dados\macoratti.txt no modo append. O
argumento true do construtor especifica a operao para anexar dados ao arquivo. No primeiro WriteLine() a string
ser anexada ao arquivo e no segundo WriteLine() estamos reabrindo o arquivo c:\dados\macoratti.txt e anexando a
nova string ao arquivo.
muito comum quando voc estiver escrevendo em um arquivo usar um array ou uma lista de strings. A melhor
forma de fazer isso usar um lao aps declarar uma instncia de um StreamWriter, conforme mostra o exemplo a
seguir:
1
using System.IO;
class Program
// Percorre o lao
10
11
12
13
14
{
// Escreve uma string formatada no arquivo
15
16
17
No exemplo, a instruo using abre e prepara o arquivo e aps concluir fecha e libera os recursos usados.
Para ler um arquivo texto utilize a classe StreamReader(), criando uma instncia da classe e usando o construtor
onde informa o nome do arquivo a ser aberto.
A seguir temos os principais membros da classe StreamReader:
Close()
Dispose()
Peek()
Read()
ReadBlock()
L um nmero especfico de
caracteres de um stream atual e
escreve os dados em um buffer
ReadLine()
ReadToEnd()
No exemplo abaixo estamos acessando o arquivo macoratti.txt e lendo uma linha do arquivo texto usando o
mtodo ReadLine(). uma boa prtica sempre verificar se o arquivo a ser lido existe ou se encontra no local
indicado.
1
using System;
using System.IO;
3
4
class Program
7
8
{
//usando a instruo using os recursos so liberados aps a concluso da operao
string linha;
10
11
12
linha = reader.ReadLine();
13
14
Console.WriteLine(linha);
15
16
A linha lida exibida no console usando a instruo Console.WriteLine(). Para ler mais de uma linha do arquivo
podemos usar um lao While e percorrer o arquivo enquanto no for encontrado um caractere null que indica o fim
de arquivo.
1
using System;
using System.IO;
namespace Operacoes_IO
class Program
10
if (File.Exists(arquivo))
11
12
13
14
try
{
using (StreamReader sr = new StreamReader(arquivo))
15
16
String linha;
17
18
19
20
Console.WriteLine(linha);
21
22
23
24
25
26
{
Console.WriteLine(ex.Message);
27
28
29
else
30
31
32
33
34
Console.ReadKey();
}
35
36
}
}
Este cdigo utiliza a classe StreamReader() para ler o arquivo macoratti.txt na pasta c:\dados.
Estamos usando o mtodo ReadLine() em um bloco While lendo linha a linha at encontrar o valor null que
corresponde ao final do arquivo : while ((linha = sr.ReadLine()) != null). Verificamos tambm se o arquivo existe (
s usar o mtodo esttico Exists() da classe File: if (File.Exists(arquivo)).
Estamos usando tambm um bloco try/catch para tratar qualquer exceo que ocorre quando do acesso e da
utilizao do arquivo e a clusula using est sendo usada para liberar de forma automtica os recursos usados para
acessar e ler o arquivo.
Dessa forma, sempre que formos abrir um recurso como um arquivo, primeiro devemos verificar se ele existe e
sempre devemos realizar o tratamento de exceo usando o bloco try/catch quando formos tratar arquivos com as
classes do namespace System.IO.
Finalmente no devemos esquecer de liberar os recursos usados.