c# - lendo e escrevendo em arquivos textos e binários
TRANSCRIPT
1/7/2014 C# - Lendo e escrevendo em arquivos textos e binários
http://www.macoratti.net/14/04/c_iotb1.htm 1/6
C# - Lendo e escrevendo em arquivos textos(StreamReader/StreamWriter)
Confuso com a profusão de classes e métodos disponíveis 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 faço para arquivos textos ?
Antes de irmos direto para a parte prática vamos tentar ter uma v isão geral da hierarquia de classes que a plataforma .NET oferece
para esta finalidade.
Um pouco de teoria
As operações de input e output na plataforma .NET são gerenciadas pela classe abstrata Stream que esta no namespace System.IO.
Se você conhece os fundamentos da programação orientada a objetos deve saber que uma classe abstrata não pode ser instanciada
diretamente.
Portanto você não pode usar a classe Stream diretamente para acessar arquivos.
Ora bolas, então para que serve esta classe ?
Serve para padronizar e fornecer um contrato com métodos e propriedades que devem ser implementadas por outras classes que
herdam da classe Stream.
Notou a palavra mágica herança ?
Pois bem a plataforma .NET oferece uma hierarquia de classes que podemos usar para realizar operações 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 div idi-las em duas categorias:
A primeira categoria contém todas as classes que implementam a classe Stream para uma operação específica de I/O. Essas classes
são:
FileStream, para trabalhar com arquivos;
NetworkStream, para transferência de dados em rede;
MemoryStream, para a troca de dados em memória;
A segunda categoria contém classes derivadas de Stream que reforçam o que a classe Stream tem a oferecer. Elas podem ser
considerados como uma camada sobre a funcionalidade básica oferecida pela classe Stream.
Esta categoria inclui os seguintes classes:
BufferedStream, que permitem realizar a operação tamponada sobre um stream. Dev ido ao fato que os dados não são gravados
1/7/2014 C# - Lendo e escrevendo em arquivos textos e binários
http://www.macoratti.net/14/04/c_iotb1.htm 2/6
diretamente para o stream, o número de operações I/O necessários para executar a operação é menor, aumentando assim, a
execução da operação;
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 métodos e propriedades
desta classe que as demais classes tem que implementar:
1- Propriedades
CanRead obtém um valor indicando se o fluxo atual oferece suporte à leitura.
CanSeek obtém um valor indicando se o fluxo atual oferece suporte a busca.
CanTimeout Obtém um valor que determina se o fluxo atual da suporte ao time out.
CanWrite Obtém um valor indicando se o fluxo atual oferece suporte a escrita.
Length Obtém o tamanho em bytes do fluxo.
Position Obtém ou define a posição no fluxo atual.
ReadTimeout Obtém ou define um valor, em milisegundos, que determina quanto tempo o fluxo tentará ler antes do time out.
WriteTimeoutObtém ou define um valor, em milisegundos, que determina quanto tempo o fluxo tentará escrever antes do time out.
2- Métodos (Os principais)
BeginRead Inicia uma operação de leitura assíncrona. (Considere usar ReadAsync)
BeginWrite Inicia uma operação de gravação assíncrona. (Considere usar WriteAsync)
CloseFecha o fluxo atual e libera os recursos (como os soquetes e identificadores de arquivo) associados com o fluxo atual.
Em vez de chamar esse método, certifique-se de que o fluxo seja descartado corretamente.
CopyTo(Stream) Le os bytes do fluxo atual e escreve-os em outro fluxo.
Dispose() Libera os recursos usados pelo Stream.
EndRead Aguarda a leitura assíncrona pendente terminar. (Considere usar ReadAsync)
EndWrite Termina uma operação de gravação assíncrono. (Considere usar WriteAsync)
Equals(Object) Verifica se o objeto especificado é igual ao objeto atual. (Herdado de Object.)
FinalizePermite que um objeto tente liberar recursos e executar outras operações de limpeza antes que ele seja recuperado
pela coleta de lixo. (Herdado de Object.)
FlushLimpa todos os buffers para esse fluxo e faz com que alguns dados armazenados em buffer sejam gravados no
dispositivo subjacente.
Read Lê uma sequência de bytes de fluxo atual e avança a posição no fluxo pelo número de bytes lidos.
Seek Define a posição no fluxo atual.
SetLength Define o comprimento de fluxo atual.
ToString Retorna uma string que representa o objeto atual. (Herdado de Object.)
WriteGrava uma sequência de bytes no fluxo atual e avança a posição atual dentro desse fluxo pelo número de bytes
escritos.
(fonte: http://msdn.microsoft.com/pt-br/library/system.io.stream%28v=vs.110%29.aspx - acessado em fevereiro de 2014)
Então 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 herança das principais classes
para Input/OutPut.
1/7/2014 C# - Lendo e escrevendo em arquivos textos e binários
http://www.macoratti.net/14/04/c_iotb1.htm 3/6
As classes TextReader/TextWriter representam um leitor/escritor que podem ler/escrever uma série sequencial de caracteres. Elas
são classes abstratas e não podem ser instanciadas diretamente.
Observe que as classes StreamReader/StreamWriter herdam de TextReader e de TextWriter.
Concluímos assim que StreamReader é um tipo de TextReader e que StreamWriter é um tipo de TextWriter.
Assim um StreamReader obtém os seus dados de um fluxo ou stream que pode se representado por dados que estão na memória, em
um arquivo ou v indo de uma porta serial, v ídeo ou capturado em um dispositivo.
Dessa forma um StreamReader possui uma implementação específica para leitura de caracteres de um stream como um arquivo.
StreamReader Implementa um TextReader que lê caracteres de um fluxo de
bytes em uma codificação específica.
TextReader Representa um leitor que pode ler uma série seqüencial de
caracteres.(classe abstrata)
Conclusão: 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 começar mostrando como criar e escrever em arquivos texto usando StreamWriter.
A seguir as principais propriedades e métodos da classe StreamWriter:
AutoFlush()
Obtém ou define um valor indicando se o
StreamWriter irá liberar o buffer no fluxo
subjacente após cada chamada a Write.
Close()Fecha o objeto atual de StreamWriter e o fluxo
subjacente
Dispose()Libera os recursos usados pelo objeto de
TextWriter
Flush()
Limpa todos os buffers para o gravador atual e
faz com que todos os dados armazenados em
buffer sejam gravados no fluxo subjacente.
NewLine()
Write() Grava no fluxo.
WriteLine()Grava no fluxo seguido de um terminador de linha
Para começar temos que referenciar o namespace System.IO e declarar e inicializar uma nova instância de StreamWriter usando um
de seus construtores.
StreamWriter writer = new StreamWriter("macoratti.txt")
Nesta declaração um novo StreamWriter é inicializado com o nome do arquivo igual 'macoratti.txt' (você pode usar qualquer extensão como .dat por exemplo)
Se o arquivo não existir ela será criado. No exemplo como não definimos um local para o arquivo ele será criado no mesmo diretório
1/7/2014 C# - Lendo e escrevendo em arquivos textos e binários
http://www.macoratti.net/14/04/c_iotb1.htm 4/6
da aplicação.
Para escrever no arquivo podemos usar o método Write() ou WriteLine() . Estes métodos possuem diversas sobrecargas.
using (StreamWriter writer = new StreamWriter("macoratti.txt"))
{
writer.Write("Macoratti .net ");
writer.WriteLine("Quase tudo para Visual Basic");
writer.WriteLine("http://www.macoratti.net");
}
No código o método Write() escreve uma linha e não anexa uma linha. Já o método WriteLine() anexa uma nova linha ("\r\n") ao
arquivo a cada chamada.
Observe que estamos usando a cláusula using de forma a liberar os recursos usados na operação após sua utilização. Nunca esqueça
de liberar os recursos usados e também verifique sempre se o arquivo existe quando necessário.
Se desejarmos escrever em um arquivo já existente anexando linhas ao arquivo podemos usar o construtor : StreamWriter(string
caminho, bool anexa)
Inicializa uma nova instância do StreamWriter para o arquivo no caminho especificado, usando a codificação padrão e buffer. Se o
arquivo existir, pode ser tanto sobrescrito ou anexado. Se o arquivo não existir, este construtor cria um novo arquivo.
using System.IO;
class Program
{
static void Main()
{
// 1: Escreve um linha para o novo arquivo
using (StreamWriter writer = new StreamWriter("C:\\dados\\macoratti.txt", true))
{
writer.WriteLine("Macoratti .net");
}
// 2: Anexa uma linha ao arquivo
using (StreamWriter writer = new StreamWriter(@"C:\dados\macoratti.txt", true))
{
writer.WriteLine("Quase tudo para Visual Basic");
}
}
}
No código acima inicia inicializando um novo StreamWriter e abre o arquivo c:\dados\macoratti.txt no modo append. O argumento
true do construtor especifica a operação 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 laço após declarar uma instância de um StreamWriter conforme mostra o exemplo a seguir:
using System.IO;
class Program
{
static void Main()
{
// Usamos um tipo var que mais
simples
using (var writer = new
StreamWriter("macoratti.txt"))
{
1/7/2014 C# - Lendo e escrevendo em arquivos textos e binários
http://www.macoratti.net/14/04/c_iotb1.htm 5/6
// Percorre o laço
for (int i = 0; i < 10; i++)
{
// Escreve uma string
formatada no arquivo
writer.Write("{0:0.0} ", i);
}
}
}
}
No exemplo a instrução using abre e prepara o arquivo e após concluir fecha e libera os recursos usados.
Para ler um arquivo texto utilize a classe StreamReader() criando uma instância 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() Fecha o StreamReader atual
Dispose() Libera os recursos usado pelo StreamReader
Peek()Retorna o próximo caractere disponível mas
não o utiliza
Read()Lê o próximo caractere ou conjunto de
caracteres de um stream
ReadBlock()Lê um número específico de caracteres de um
stream atual e escreve os dados em um buffer
ReadLine()Lê uma linha de caractere do stream atual e
retorna os dados em uma string
ReadToEnd()Lê o stream da posição atual até o fim do
stream
No exemplo abaixo estamos acessando o arquivo 'macoratti.txt' e lendo uma linha do arquivo texto usando o método ReadLine(). É
uma boa prática sempre verificar se o arquivo a ser lido existe ou se encontra no local indicado.
using System;
using System.IO;
class Program
{
static void Main()
{
//usando a instrução using os recursos são liberados
após a conclusão da operação
string linha;
us ing (StreamReader reader = new
StreamReader("macoratti.txt"))
{
linha = reader.ReadLine();
}
Console.WriteLine(linha);
}
}
A linha lida é exibida no console usando a instrução Console.WriteLine():
Para ler mais de uma linha do arquivo podemos usar um laço While e percorrer o arquivo enquanto não for encontrado um caractere
null que indica o fim de arquivo.
using System;
using System.IO;
namespace Operacoes_IO
{
class Program
{
static void Main(string[] args)
1/7/2014 C# - Lendo e escrevendo em arquivos textos e binários
http://www.macoratti.net/14/04/c_iotb1.htm 6/6
{
string arquivo = @"C:\dados\macoratti.txt" ;
if (File.Exists(arquivo))
{
try
{
us ing (StreamReader sr = new
StreamReader(arquivo))
{
String linha;
// Lê linha por linha até o final do
arquivo
while ((linha = sr.ReadLine()) != null)
{
Console.WriteLine(linha);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
else
{
Console.WriteLine(" O arquivo " + arquivo
+ "não foi localizado !" );
}
Console.ReadKey();
}
}
}
Este código utiliza a classe StreamReader() para ler o arquivo macoratti.txt na pasta c:\dados.
Estamos usando o método 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)
Estamos verificando se o arquivo existe usando o método estático Exists() da classe File: if (File.Exists(arquivo))
Estamos usando também um bloco try/catch para tratar qualquer exceção que ocorre quando do acesso e da utilização do arquivo.
A cláusula using esta sendo usada para liberar de forma automática os recursos usados para acessar e ler o arquivo.
Dessa forma sempre que formos abrir um recurso como um arquivo primeiro devemos verificar e o mesmo existe e sempre devemos
realizar o tratamento de exceção usando o bloco try/catch quando formos tratar arquivos com as classes do namespace System.IO.
Finalmente não devemos esquecer de liberar os recursos usados.
João 5:39 Examinais as Escrituras, porque julgais ter nelas a vida eterna; e são elas que dão testemunho de mim;
João 5:40 mas não quereis vir a mim para terdes vida!
João 5:41 Eu não recebo glória da parte dos homens;
João 5:42 mas bem vos conheço, que não tendes em vós o amor de Deus.
Referências:
Seção VB .NET do Site Macoratti.net
Super DVD .NET - A sua porta de entrada na plataforma .NET
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Seção C# do site Macoratti.net
C # - Tratando arquivos textos - Inserindo texto em ... - Macoratti.net
VB.NET - Lendo e escrevendo em arquivo Textos - Macoratti.net
VB 2005 Streams - Macoratti.net
VB .NET - Formatando arquivos textos - Macoratti.net
José Carlos Macoratti