Arquivo

Archive for the ‘.NET Framework’ Category

Serialization .NET

Olá pessoal, hoje eu vou falar sobre serialização de dados com o .NET. Para quem não sabe oque é serialização pense na seguinte situação, você precisa transferir uma coleção de objetos de sua aplicação para outra aplicação através da rede. Para fazer isso você precisaria transformar sua coleção em um XML e enviar para a outra aplicação. Este processo de transformação da coleção de objetos para um XML pode ser considerado uma serialização.

Dentro do namespace System.Runtime.Serialization.Formatters.Binary você tem a classe BinaryFormatter que nos permite transformar dados de nossa aplicação (string, coleção de objetos e etc.) em um arquivo binário serializado. Segue abaixo um exemplo de como serializar uma string.

  1. FileStream fileStream = new FileStream("ArquivoBinarioSerializado", FileMode.CreateNew);
  2. BinaryFormatter binFtr = new BinaryFormatter();
  3. binFtr.Serialize(fileStream, "franciscogoncalves.wordpress.com");
  4. fileStream.Close();

Na primeira linha eu criei um FileStream para criar um arquivo com o nome de “ArquivoBinarioSerializado”. Na segunda linha eu instanciei a classe BinaryFormatter. Na terceira linha é que a serialização realmente acontece. Estou dizendo para que a string “franciscogoncalves.wordpress.com” seja serializada dentro do arquivo que estou criando com o FileStream. Na última linha apenas chamo o método close do FileStream. Se você pode verificar na pasta raiz de seu projeto que um arquivo com dados serializados foi criado. E para deserializar utilize o seguinte exemplo.

  1. FileStream fileStream = new FileStream("ArquivoBinarioSerializado", FileMode.Open);
  2. BinaryFormatter binFtr = new BinaryFormatter();
  3. string data = (string)binFtr.Deserialize(fileStream);
  4. fileStream.Close();
  5. Console.WriteLine(data);

A diferença entre o primeiro trecho de código e o segundo é que no segundo o FileStream está com o FileMode configurado para abrir um arquivo ao invés de criar. Na terceira linha estou chamando o método Deserialize passando como parâmetro o FileStream. É muito importante que você saiba qual é o tipo do conteúdo do arquivo. No caso eu sei que o conteúdo do arquivo é uma string, por isso eu faço um cast para string. E na última linha eu exibo o resultado. Você pode verificar que o conteúdo é exatamente o mesmo que eu havia serializado no exemplo anterior.

A serialização binária é muito útil quando precisamos trafegar dados entre aplicações .NET, porém quando precisamos trafegar informações para outro tipo de plataforma utilizamos a serialização Soap que é baseado em XML. Para utilizar adicione o assembly  System.Runtime.Serialization.Formatters.Soap e utilize os seguintes exemplos para para:

Serializar

  1. FileStream fileStream = new FileStream("ArquivoSoapSerializado", FileMode.CreateNew);
  2. SoapFormatter soapFtr = new SoapFormatter();
  3. soapFtr.Serialize(fileStream, "franciscogoncalves.wordpress.com");
  4. fileStream.Close();

Deserializar

  1. FileStream fileStream = new FileStream("ArquivoSoapSerializado", FileMode.Open);
  2. SoapFormatter soapFtr = new SoapFormatter();
  3. string data = (string)soapFtr.Deserialize(fileStream);
  4. fileStream.Close();
  5. Console.WriteLine(data);

Você pode perceber que o arquivo gerado tem uma formatação diferente quando utilizamos o SoapFormatter.

Você também pode serializar suas próprias classes, basta que você a decore com o atributo Serializable. Segue abaixo um exemplo.

  1. [Serializable]
  2. public class Pessoa
  3. {
  4.     public int idPessoa { get; set; }
  5.     public string nome { get; set; }
  6.     public int idade { get; set; }
  7.     public int anoNascimento { get; set; }
  8. }

E para você serializar ou deserializar basta usar os exemplos acima trocando a string pela seu objeto.

O Serialization permite que você configure como a serialização da classe pode funcionar. Por exemplo, caso você tenha duas versões diferente da classe Pessoa você pode utilizar o atributo OptionalField na propriedade escolhida. Isto significa que poderá serializar/deserializar de uma classe para outra mesmo que não exista a propriedade em uma delas.

  1. [OptionalField]
  2. public int idPessoa { get; set; }

Outro atributo interessante é o NonSerialized que indica que esta propriedade não será serializada. Veja abaixo um exemplo.

  1. [NonSerialized]
  2. public int anoNascimento { get; set; }

Você também pode controlar como será a deserialização. Por exemplo: a propriedade anoNascimento não será serializada, porém eu posso calcular este valor no momento da deserialização implementando a Interface IDeserializationCallback.

  1. [Serializable]
  2. public class Pessoa : IDeserializationCallback
  3. {
  4.     public int idade { get; set; }
  5.     [NonSerialized]
  6.     public int anoNascimento { get; set; }
  7.     public void OnDeserialization(object sender)
  8.     {
  9.         anoNascimento = DateTime.Now.Year – idade;
  10.     }

 

É isso ai pessoal, espero que tenham gostado do artigo e espero que ele tenha sido útil. Até o próximo.

Advertisement
Categorias:.NET Framework Etiquetas:

Encoding .NET

Hoje vamos falar sobre como utilizar as funções de Encoding no .NET. Para isso primeiro é necessário que tenhamos uma visão geral sobre os padrões de encoding existentes.

Você pode imaginar os padrões de encoding como se fossem uma lista com todos os caracteres possíveis dentro daquele padrão. Por exemplo: o padrão ASCII contêm somente caracteres da língua inglesa e alguns tipos de pontuação. Como o ASCII não atendia regiões além das que falam a língua inglesa foram criados outros padrões como o UTF8, UTF16 entre outros.

Dentro do namespace System.Text temos a classe Encoding que centraliza todo o trabalho que você teria que fazer quanto se utiliza Encoding. Por exemplo: para listar todos encodings suportados no seu computador utilize o seguinte código.

  1. EncodingInfo[] ei = Encoding.GetEncodings();
  2. foreach (EncodingInfo e in ei)
  3. {
  4.     Console.WriteLine(e.CodePage + "-" + e.Name + "-" + e.DisplayName);
  5. }

A classe Encoding tem um método estático GetEncodings que retorna um array de EncodingInfo. O mesmo tem algumas propriedades que podem ser utilizadas para recuperar algumas informações. No exemplo acima eu utilizei as propriedades CodePage, Name e DisplayName.

Cada caracter que você tem dentro de uma string na verdade ele corresponde a um byte de acordo com o encoding escolhido. Você pode verificar a diferença de bytes executando estas seqüencias de código.

  1. Encoding e = Encoding.GetEncoding("Korean");
  2. byte[] encoded;
  3. encoded = e.GetBytes("Gonçalves");
  4. for (int i = 0; i < encoded.Length; i++)
  5. {
  6.     Console.WriteLine("Byte {0}: {1}", i, encoded[i]);
  7. }

  1. Encoding e = Encoding.GetEncoding("IBM860");
  2. byte[] encoded;
  3. encoded = e.GetBytes("Gonçalves");
  4. for (int i = 0; i < encoded.Length; i++)
  5. {
  6.     Console.WriteLine("Byte {0}: {1}", i, encoded[i]);
  7. }

Quando você executar este código você irá perceber que o caracter “ç” é representado de maneiras diferentes dependendo do encoding utilizado. No caso IBM860 é o codePage do encoding “Portuguese”.

O muito importante você trabalhar com o encoding correto quando você estiver escrevendo ou lendo um arquivo. No exemplo abaixo eu demonstro como escrever em um arquivo de texto utilizando o encoding UTF7. E logo em seguida eu demonstro como será a leitura do mesmo utilizando o encoding correto e o encoding errado.

  1. StreamWriter sw = new StreamWriter("teste.txt", false, Encoding.UTF7);
  2. sw.WriteLine("Francisco Gonçalves");
  3. sw.Close();
  4. StreamReader sr = new StreamReader("teste.txt", Encoding.UTF7);
  5. Console.WriteLine(sr.ReadToEnd());
  6. sr.Close();
  7. StreamReader sr1 = new StreamReader("teste.txt", Encoding.UTF8);
  8. Console.WriteLine(sr1.ReadToEnd());
  9. sr1.Close();

Você pode perceber que se usarmos o encoding errado podemos ter alguns problemas na hora da leitura.

E é isso ai pessoal, espere que o artigo tenha seja útil para o seu dia-a-dia. Até a próxima.

Categorias:.NET Framework Etiquetas:

Regex .NET – Regular Expression

Olá pessoal, neste artigo irei demonstrar como utilizar as famosas Regular Expression (Expressões Regulares) no .NET. Para quem não sabe Regular Expression de acordo com o site Wikipédia é uma forma concisa e flexível de identificar cadeias de caracteres dentro de um texto independente de plataforma. Em outras palavras significa que você pode utiliza-la quando deseja pesquisar seu texto tendo como filtro uma padrão de caracteres, ou então verificar se um formato de texto é válido e entre outras coisas. O objetivo deste artigo é demonstrar como o .NET trabalha com essas expressões regulares e não como as expressões funcionam. Para mais informações sobre Regular Expression segue abaixo alguns links.

http://pt.wikipedia.org/wiki/Express%C3%A3o_regular – Wikipédia

http://msdn.microsoft.com/en-us/library/az24scfc.aspx – Site da Microsoft

http://regexlib.com/Search.aspx – Contém uma série de expressões como cpf, cnpj e etc..

No mundo .NET nós temos o namespace System.Text.RegularExpression que permite trabalharmos com as Expressões.

Para fazer uma simples validação utilizamos o método estático IsMatch da classe Regex. Segue abaixo um exemplo.

  1. Console.WriteLine(Regex.IsMatch("12345", @"^\d{5}"));
  2. Console.WriteLine(Regex.IsMatch("1234", @"^\d{5}"));

 

Nestes dois exemplos estou utilizando a expressão “^\d{5}” que significa 5 dígitos ou mais para validar a string “12345” e a string “1234”. No primeiro caso o Regex.IsMatch retorna true já no segundo o retorno é falso, indicando que a string não passou pelo teste da expressão.

No método IsMatch você ainda tem a opção de configurar o funcionamento do mesmo utilizando o enumerador RegexOptions. Segue abaixo um exemplo de utilização, porém o enumerador tem muitas opções para você escolher.

  1. Regex.IsMatch("12345", @"^\d{5}", RegexOptions.Compiled)

Com o método Match você pode extrair partes do texto que estão de acordo com sua regular expression. Segue abaixo um exemplo:

  1. Match m = Regex.Match("Blog do: Francisco Gonçalves", "Blog do: (.*$)");
  2. Console.WriteLine(m.Groups[1]);
  3. Console.WriteLine(m.Success);

 

Na primeira linha estou passando como parâmetro a string que será verificada e como segundo parâmetro qual será o pattern de extração. Na segunda linha estou verificando o primeiro grupo que foi extraído do texto e na última linha estou verificando a propriedade que indica se a extração foi um sucesso ou não.

A classe Regex tem um método estático para substituição de string chamado Replace. Veja como utilizar.

  1. Console.WriteLine(Regex.Replace("1a2v3c", @"[\d]", "#"));

 

Neste exemplo estou substituindo todos os numerais da string “1a2v3c” por “#”.

Este foi um post pequeno, porém espero que seja útil para o seu dia-a-dia. Até o próximo.

Categorias:.NET Framework Etiquetas:,

Instrumentação .NET – WMI

No podemos acessar uma série de informações do Windows através do Windows Management Instrumentation (WMI) como por exemplo versão do sistema operacional, temperatura do processador, nome dos HD´s instalados, quais são os Drives entre outras coisas. Para uma referência completa verifique o link “Classes WMI” no final deste artigo. Neste post irei descrever como executar as operações básicas de monitoramento.

Para se conectar ao WMI do Windows adicione o namespace System.Management e utilize o seguinte código:

  1. ManagementScope scope = new ManagementScope(@"\\localhost\root\cimv2");
  2. scope.Connect();

 

No exemplo acima estou instanciando uma classe do tipo ManagementScope e chamando o método para conectar no WMI.

O Framework nos permite utilizar uma subset do SQL chamada WMI Query Language (WQL) para realizar consultas no WMI do Windows. Para isso você terá que criar um ObjectQuery passando como parâmetro no construtor o WQL criado. Segue abaixo o exemplo.

  1. ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_LogicalDisk");

 

Neste caso estou selecionando todos os drives lógicos que o Windows reconhece. Existem várias querys que podem ser realizadas, para uma referencia completa veja os links no final deste artigo.

Para realizar a consulta siga o exemplo abaixo:

  1. ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
  2. ManagementObjectCollection queryCollection = searcher.Get();
  3. foreach (ManagementObject m in queryCollection)
  4. {
  5.     Console.WriteLine("{0} {1}", m["Name"].ToString(), m["Description"].ToString());
  6. }

 

Na linha 1 estou criando o objeto ManagementObjectSearcher passando como parâmetro o scope e a query. Na segunda linha eu executo a consulta chamando o método Get e retorno a coleção atribuindo ao objeto ManagementObjectCollection. Nas linhas finais eu executo um foreach através da coleção e retorno o nome e a descrição do drive passando como parâmetro suas chaves respectivamente. Para uma referencia completa das chaves, acessem os links no final deste artigo.

Outra opção é você monitorar os eventos WMI para que quando algum evento executar o seu código será chamado. Segue abaixo como fazer isso.

  1. WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent",
  2.                             new TimeSpan(0, 0, 1),
  3.                             "TargetInstance isa 'Win32_Process'");
  4. ManagementEventWatcher watcher = new ManagementEventWatcher(query);
  5. ManagementBaseObject e = watcher.WaitForNextEvent();
  6. Console.WriteLine(((ManagementBaseObject)e["TargetInstance"])["Name"]);
  7. watcher.Stop();

 

Na primeira linha estou criando o Objeto WqlEventQuery dizendo quais eventos eu quero monitorar. Na quarta linha eu crio o watcher que inicia o monitoramento. Na linha 5 eu digo para a aplicação que aguarde até que algum evento WMI seja executado. Na penúltima linha eu recupero qual o nome do processo que foi criado e na última linha eu paro o monitoramento.

Outra forma de realizar este monitoramento é através de eventos do watcher. Isto melhora sua aplicação pois a mesma não terá que ficar parada esperando que algum evento aconteça. Segue abaixo como fazer.

  1. watcher.EventArrived += new EventArrivedEventHandler(handler);
  2. watcher.Start();

 

Após criar o watcher estou associando um método ao evento EventArrived do mesmo, para que quando algum evento acontecer ele chamará automaticamente este método. Na última linha estou dizendo para o watcher começar o monitoramento.

E chegamos ao fim de mais um artigo desta série de instrumentação. Espero que tenham gostado e que seja útil para seu dia a dia.

Classes WMI : http://msdn.microsoft.com/en-us/library/aa394554.aspx

Scripts WMI: http://msdn.microsoft.com/en-us/library/aa394585(v=VS.85).aspx

Categorias:.NET Framework Etiquetas:,

Instrumentação .NET – Processos

Fala galera. Neste artigo vou demonstrar como desenvolver a maioria das funções que você encontra no gerenciador de tarefas do Windows. Segue abaixo um print do TaskManager do Windows que você pode acessar digitando “taskmgr” no executar do menu iniciar. (Se você identificar algum vírus na minha lista de processos me avise..rs).

Nova Imagem (1)

Dentro no namespace System.Diagnostics você tem a classe Process que permite você executar um novo processo, monitorar algum existente, fechar um processo e outras coisas mais. Segue abaixo um exemplo de como executar um novo processo.

  1. Process.Start("Calc");
  2. Process.Start("Notepad", @"c:\Teste.txt");

 

No exemplo acima eu primeiro iniciei uma instancia da calculadora do Windows. Na segunda linha eu estou iniciando uma instancia do notepad do Windows passando como parâmetro o arquivo “C:\Teste.txt” para ser aberto pelo notepad.

Outra forma de iniciar um processo é utilizando a classe ProcessStartInfo que é utilizada quando você precisa realizar mais configurações para iniciar um processo ou quando você precisa criar essas configurações de modo dinâmico ou em etapas diferentes. Segue abaixo um exemplo.

  1. ProcessStartInfo psi = new ProcessStartInfo();
  2. psi.Arguments = @"c:\windows\win.ini";
  3. psi.FileName = "Notepad";
  4. Process.Start(psi);

O ProcessStarInfo tem várias propriedades que permitem você tratar a inicialização do seu processo. Abaixo eu demonstro algumas propriedades para você configurar sobre qual domínio sua propriedade ser inicializada.

  1. psi.Domain = "Dominio.com";
  2. psi.UserName = "Francisco";

 

A classe Process contém um método estático que retorna todos os processos que estão executando no computador atualmente. Para utiliza-lo chame o método GetProcesses como demonstrado no exemplo abaixo.

  1. foreach (Process p in Process.GetProcesses())
  2. {
  3.    Console.WriteLine(p.Id); //Id do Processo
  4.    Console.WriteLine(p.ProcessName); //Nome do Processo
  5.    Console.WriteLine(p.MainModule); //Módulo principal da execução
  6.    Console.WriteLine(p.Responding); //Verifica se a aplicação esta respondendo
  7.    Console.WriteLine(p.TotalProcessorTime); //Tempo de processamento
  8.    Console.WriteLine(p.VirtualMemorySize64); //Total de memória virtual
  9. }

 

Além monitorar os processos você ainda tem a opção de gerencia-los. Segue abaixo alguns exemplos.

  1. Process p = Process.Start("Notepad", @"c:\Teste.txt");
  2. p.CloseMainWindow();
  3. p.Kill();
  4. p.Start();
  5. p.WaitForExit();

Na linha 2 eu estou dizendo para que o notepad feche naturalmente, isto quer dizer que o notepad irá executar seu comportamento padrão de execução exibindo aquela tela para salvar as alterações. Na terceira linha estou matando o processo, funciona da mesma forma que o “Finalizar processo” do gerenciador de tarefas. Na quarta linha estou iniciando o processo novamente e na ultima linha eu digo para o nosso processo esperar que o notepad feche para continuarmos a execução.

A classe processo nos permite retornar todos os módulos associados ao processo utilizando o método modules. Segue o exemplo demonstrando como utilizar. 

  1. foreach (ProcessModule pm in p.Modules)
  2. {
  3.     Console.WriteLine(pm.FileName); //Arquivo do Módulo
  4.     Console.WriteLine(pm.ModuleMemorySize); //Memória utilizada
  5.     Console.WriteLine(pm.ModuleName); //Nome do Módulo
  6.     Console.WriteLine(pm.FileVersionInfo.ToString()); //Informação sobre a versão
  7. }

Espero que tenham gostado e até o próximo artigo.

Categorias:.NET Framework Etiquetas:,

Instrumentação .NET – Contadores de Performance

Olá amigos..

Neste artigo irei demonstrar como monitorar sua aplicação com contadores de performance.

O Windows tem uma ferramenta para gerenciar contadores de performance chamada “perfmon”. Você pode acessa-la digitando “perfmon” no executar do Windows.

Nova Imagem

Nesta ferramenta você pode monitorar uma série de contadores que já estão configurados no seu computador. Utilizando o namespace System.Diagnostics você poderá criar um contador de performance para ser monitorado, você também poderá ler um contador a partir de sua aplicação. Vamos aprender como ler um contador de performance.

PerformanceCounter contadorPerformance = new PerformanceCounter(“Processor”, “% Processor Time”, “_Total”);

No código acima estou indicando que quero criar um contador de Performance baseado em um já existente no sistema operacional. No caso específico estou indicando a categoria “Processor”, Indicando o contador “% Processor Time” e a instancia “_Total”.

Depois de instanciado o contador você poderá monitora-lo. Segue abaixo um exemplo.

for (int i = 0; i < 10; i++)
{
    Thread.Sleep(1000);
    Console.WriteLine(contadorPerformance.NextValue());
}

No exemplo acima eu utilizei a propriedade NextValue para recuperar qual o valor calculado do contador.

Para criar um contador de performance você pode utilizar o seguinte exemplo:

PerformanceCounterCategory.Create(“Categoria do meu Contador”, “Ajuda da Categoria”,
                PerformanceCounterCategoryType.SingleInstance, “Meu contador”, “Ajuda do Meu contador”);

O primeiro parâmetro indica o nome da categoria a ser criada, seguido pelo parâmetro que indica o Help da mesma, o terceiro parâmetro indica a quantidade de instancias o contador poderá ter, já o quarto parâmetro indica o nome do contador e logo em seguida vem o parâmetro que indica o Help do mesmo. Segue abaixo alguns métodos interessantes para o gerenciamento de contadores.

PerformanceCounterCategory.Delete(“Categoria do meu Contador”); //Exclui uma categoria
PerformanceCounterCategory.CounterExists(“Meu contador”, “Categoria do meu Contador”); //Verifica se um contador existe
PerformanceCounterCategory.Exists(“Categoria do meu Contador”); //Verifica se uma categoria existe
PerformanceCounterCategory.GetCategories(); //Retorna todas as categorias cadastradas

Você também pode adicionar vários contadores a mesma categoria.

CounterCreationDataCollection conts = new CounterCreationDataCollection();
conts.Add(new CounterCreationData(“Contador 1”, “Ajuda do Contador 1”, PerformanceCounterType.NumberOfItems64));
conts.Add(new CounterCreationData(“Contador 2”, “Ajuda do Contador 2”, PerformanceCounterType.NumberOfItems64));
PerformanceCounterCategory.Create(“Categoria do meu Contador”, “Ajuda da Categoria”,
PerformanceCounterCategoryType.SingleInstance, conts);

Você pode verificar o parâmetro criado na ferramenta perfmon do Windows. Clique em um botão com o sinal de positivo “+” e procure o sua categoria criada e seu contador criado e adicione ao monitoramento.

PerformanceCounter contPerf = new PerformanceCounter(“Categoria do meu Contador”, “Meu contador”, false);
for (int i = 0; i < 100; i++)
{
   contPerf.Increment();
   Console.WriteLine(contPerf.NextValue());
}

No exemplo acima eu instancia o contador criado no exemplo anterior passando um parâmetro booleano como false. Este parâmetro indica que o contador não é read-only. O método “Increment” adiciona o valor 1 no contador. Você pode verificar o incremento tanto no console quanto no perfmon. Segue abaixo alguns métodos úteis para utilização do contador de performance.

contPerf.RawValue = 5; //Configura um valor para o contador
contPerf.Increment(); //Adiciona 1 ao contador. Tipo thread-Safe
contPerf.Decrement(); //Remove 1 ao contador. Tipo thread-Safe
contPerf.IncrementBy(2); //Adiciona 2 ao contador. Tipo thread-Safe
Console.WriteLine(contPerf.CategoryName); //Recupera a categoria do contador
Console.WriteLine(contPerf.CounterHelp); //Recupera o help do contador
Console.WriteLine(contPerf.CounterName); //Recupera o nome do contador
Console.WriteLine(contPerf.CounterType); //Recupera o tipo do contador
Console.WriteLine(contPerf.InstanceName); //Recupera o nome da instancia do contador

E é isso ai pessoal, espero que a partir de hoje você saiba como monitorar a performance de sua aplicação de uma forma que seja de fácil leitura para o pessoal de Infra da sua empresa.

Instrumentação .NET – Debug e Trace

Quantas vezes nós já passamos por situações em que após realizarmos todos os testes em nossa maquina, confirmamos que o sistema esta ok, porém quando enviamos para o servidor de homologação o sistema parece outro, cheio de erros. E a pior parte é que não podemos debugar no ambiente de homologação.  Isto se resume da frase: “Na minha maquina funciona”.

Para ajudar a resolver esses problemas o .NET Framework disponibiliza as classes de Debug e Trace dentro do namespace System.Diagnostics. As duas classes são implementadas da mesma maneira e tem comportamento semelhante. A principal diferença entre elas é que a classe Trace é utilizada quando sua aplicação esta compilada em modo de release e a Debug quando esta compilada em modo de Debug. Essas classes nos permitem criar logs, mensagens, PopUp entre outros para monitorar a aplicação.

Vou demonstrar como utilizar essas classes usando como exemplo a classe Debug,  mas você pode substituir pela classe Trace caso seja necessário.

Debug.Write(“Mensagem: Debug”); //Escreve um texto.

O texto irá aparecer na janela Output do Visual Studio.

image

O texto apareceu na janela de Output porque esta configurado por padrão para fazer isso. A saída do texto pode ser configurada com ajuda dos Listeners. Segue abaixo alguns exemplos.

Debug.Listeners.Add(new DefaultTraceListener()); //Listener padrão. Exibe as mensagens na janela de output do VS.
Debug.Listeners.Add(new TextWriterTraceListener(“Teste.txt”)); // Grava as mensagens em um arquivo texto.
Debug.Listeners.Add(new XmlWriterTraceListener(“teste.xml”)); //Grava as mensagens em um arquivo xml.
Debug.Listeners.Add(new EventLogTraceListener(new EventLog(“DebugLog”, “.”, “DebugSource”))); //Grava as mensagens no log do Windows.
Debug.Listeners.Add(new ConsoleTraceListener()); //Exibe as mensagens em uma janela console.

Você também pode usar o web.config ou app.config para configurar os Listeners. Segue abaixo alguns exemplos.

<system.diagnostics>
   <trace autoflush =”true” indentsize=”4″>
     <listeners>
       <add name=”TextTraceListener”
            type=”System.Diagnostics.TextWriterTraceListener”
            initializeData=”output.txt” />
       <add name=”XmlWriterTraceListener”
            type=”System.Diagnostics.XmlWriterTraceListener”
            initializeData=”output.xml” />
       <add name=”ConsoleTraceListener”
           type=”System.Diagnostics.ConsoleTraceListener” />
       <remove name=”Default” />
     </listeners>
   </trace>
</system.diagnostics>

Segue abaixo alguns métodos e propriedades interessantes para serem utilizados.

Debug.Assert(false, “Mensagem”); //Exibe a mensagem caso a condição seja falsa.
Debug.Write(“Mensagem”); //Exibe a mensagem
Debug.WriteLine(“Mensagem”); //Exibe a mensagem e pula uma linha
Debug.WriteIf(true, “Mensagem”); //Exibe a mensagem caso a condição seja verdadeira
Debug.WriteLineIf(true, “Mensagem”); //Exibe a mensagem caso a condição seja verdadeira e pula uma linha
Debug.Fail(“ErrorMensagem”); //Exibe uma mensagem de Erro.
Debug.Flush(); //Escreve toda as mensagem que estiverem na memória.
Debug.IndentSize = 10; // Tamanho da indentação das mensagens.
Debug.IndentLevel = 1; // Nível da indentação das mensagens.
Debug.Indent(); //Adiciona um nível de indentação para as próximas mensagens
Debug.Unindent(); //Retorna um nível de indentação para as próximas mensagens

Espero ter ajudado para que os próximos problemas que você tiver em produção não seja um pânico total. Basta usar o Trace para monitorar sua aplicação

 

 

 

Categorias:.NET Framework Etiquetas:, ,

Instrumentação .NET – EventLog

No artigo de hoje irei demonstrar como usar o Visualizador de Eventos do Windows para instrumentar sua aplicação.

Para acessar o Visualizador de Eventos do Windows digite “eventvwr” no executar. Este gerenciador de eventos disponibiliza, na janela da esquerda, todos os EventLog cadastrados no computador, o próprio Windows utiliza eles para logar eventos do sistema. Já na janela da direita, quando você selecionar um EventLog deve aparecer uma lista de eventos que foram registrados pelo Windows. Preste atenção na coluna “Fonte”, ela indica de onde veio este evento, que no nosso caso virá do aplicativo criado.

Para criar um EventLog via código para ser usado pela sua aplicação devemos importar o namespace System.Diagnostics e utilizar a classe EventLog. Como no exemplo abaixo:

EventLog.CreateEventSource(“Fonte”, “TesteLog”);// Cria um EventLog junto com uma fonte válida
EventLog.CreateEventSource(“Fonte2”, “TesteLog”);// Cria uma segunda fonte aproveitando o EventLog já criado

Você pode perceber que o EventLog contêm uma inteligência dentro da criação do evento, ou seja, caso o evento já tenha sido criado ele aproveita este evento e adiciona uma fonte nele. Outra item interessante é que, quando você cria um EventLog automaticamente ele cria um uma fonte de mesmo nome. Isto garante que o EventLog poderá ser usado.

Quando você cria uma nova fonte, você deve verificar se esta fonte já não esta registrada no computador, se já estiver registrada sua aplicação irá disparar uma exceção. Segue abaixo alguns recursos interessante que o EventLog tem para você evitar este problema e outros.

EventLog.Exists(“TesteLog”); //Verifica se existe um EventLog
EventLog.SourceExists(“TesteLog”); //verifica se existe uma fonte
EventLog.Delete(“TesteLog”); //Apaga o EventLog junto com todas as suas fontes
EventLog.DeleteEventSource(“Fonte”); //Exclui a fonte do evento
EventLog.CreateEventSource(“Fonte”, “TesteLog”);// Cria um EventLog junto com uma fonte válida

Você pode retornar uma lista de EventLogs cadastrados no computador utilizando o método GetEventLogs. Segue abaixo um exemplo.

foreach (EventLog e in EventLog.GetEventLogs())
{
    Console.WriteLine(e.Log); //Nome do Log
    Console.WriteLine(e.Source); //Recupera o nome da fonte ou registra quando você der uma entrada no log
    Console.WriteLine(e.LogDisplayName); //Nome de visualização
    Console.WriteLine(e.MachineName); //Maquina a qual o log esta referenciado
    Console.WriteLine(e.OverflowAction.ToString()); //Retorna qual será o comportamento do log caso ele fique cheio
}

Enfim vamos aprender como registrar um evento que aconteceu na sua aplicação.

EventLog log = new EventLog(“TesteLog”); //Configura qual EventLog será utilizado para gravar o evento
log.Source = “Fonte”; //Configura em qual fonte será a entrada do evento.
log.WriteEntry(“Erro da aplicação”, EventLogEntryType.Error, 1001, 1); //Efetiva as configurações anteriores e grava o evento

Perceba que o método WriteEntry aceita quatro parâmetros de entrada. O primeiro é a descrição do evento, o segundo é o tipo do evento, que pode ser de Erro, Informação, Alerta, Sucesso ou Falha em uma auditoria de segurança, já os últimos dois são utilizados para identificar mais fácil o evento, Id do Evento e Id da Categoria. É muito útil caso você crie uma documentação do seu sistema. Porém você pode usar outros métodos WriteEntry que contêm menos parâmetros.

Para ler os eventos registrados em um determinado EventLog utilize o seguinte exemplo.

EventLog log = new EventLog(“TesteLog”); //Recupera um log existente
foreach (EventLogEntry entrada in log.Entries)
{
     Console.WriteLine(entrada.Message); //Descrição do evento ocorrido
     Console.WriteLine(entrada.Category); //Categoria do evento
     Console.WriteLine(entrada.CategoryNumber); //Número da categoria do evento
     Console.WriteLine(entrada.EntryType.ToString()); //Tipo do evento
     Console.WriteLine(entrada.Index); //Índice do evento em relação a lista
     Console.WriteLine(entrada.MachineName); //Maquina a qual o evento foi geral
     Console.WriteLine(entrada.Source); //Fonte do evento
     Console.WriteLine(entrada.TimeWritten); //Qual horário o evento foi escrito
     Console.WriteLine(entrada.TimeGenerated); //Qual horário o evento foi gerado
     Console.WriteLine(entrada.UserName); //Qual usuário estava logado durante o evento
}

E finalmente, para limpar o EventLog utilize o método Clear.

EventLog log = new EventLog(“TesteLog”); //Recupera um log existente
log.Clear(); //Limpa todas as entradas de um EventLog específico

Espero que este post tenha sido simples e prático e que possa ajudar você a instrumentar sua aplicação.

Categorias:.NET Framework Etiquetas:,

Usando coleções no .NET

Muitas vezes nós usamos somente coleção genérica do tipo List para trabalhar com coleções, no entanto o Framework.NET tem uma coleção específica para cada caso desde pilha e fila que aprendemos na faculdade até ordenação automática. Vamos logo ao assunto aprender para que serve cada uma e como implementar.

Coleções

ArrayList

O ArrayList é uma simples coleção que você pode adicionar qualquer tipo de objeto e remover, navegar, ordenar entre outras funções básicas. Adicione uma referencia a classe System.Collections no seu fonte e veja abaixo um exemplo de sua implementação.

ArrayList lista = new ArrayList(); //Instancia um ArrayList
lista.Add(“Teste 1”); //Adiciona uma string “Teste 1”
lista.Add(“Teste 2”); //Adiciona uma string “Teste 2”
lista.Add(5); //Adiciona uma int.
lista.Add(new Byte()); //Adiciona um Byte
lista.Remove(“Teste 2”); //Remove uma string “Teste 2” da lista
lista.Insert(2, “Teste 3”); //Insere uma string “Teste 3” na posição 2 do array
lista.AddRange(new int[] { 1, 2, 3 }); //Adiciona um array que no caso é um array de int
lista.RemoveRange(1, 2); //Remove um range de itens. No exemplo são dois itens a partir do índice 1
lista.RemoveAt(0); //A partir de um determinado índice remove um item

Para listar todo o conteúdo que contem na sua lista utilize este exemplo.

foreach (object obj in lista)
{
     Console.WriteLine(obj.ToString());
}

O ArrayList ainda possui alguns métodos interessantes que ajudam a manipular a lista.

lista.Sort(); //Ordena o itens usando a implementação do IComparable. Os itens devem ser do mesmo tipo
lista.Reverse(); //Ordena em ordem inversa os itens
Console.WriteLine(lista.BinarySearch(5)); //Retorna o índice de item pesquisado.
Console.WriteLine(lista.Contains(5)); //Verifica se lista contem um determinado objeto

StringCollection

Esta classe trabalha de forma semelhante a classe ArrayList, porém ela é especializada em strings e não contem alguns métodos de ordenação. Segue abaixo como instanciá-la.

StringCollection listaString = new StringCollection();

Queue – Fila

Coleção que funciona como uma “Fila”, isto é, primeiro elemento que entra na coleção é o primeiro que sai. Muito útil em situações que você precisa de uma ordem de processamento por item.

Queue fila = new Queue(); //Instancia a fila
fila.Enqueue(“Teste 1”); //Adiciona um item na fila
fila.Enqueue(“Teste 2”); //Adiciona um item na fila
Console.WriteLine(fila.Dequeue()); //Retorna e remove automaticamente o primeiro item inserido na fila
fila.Peek(); //Retorna o primeiro item inserido na fila sem remove-lo da lista

Stack – Pilha

Coleção que funciona como uma “Pilha”, isto é, primeiro elemento que entra na coleção é o ultimo que sai.

Stack pilha = new Stack(); //Instancia a pilha
pilha.Push(“Teste 1”); //Adiciona um item na pilha
pilha.Push(“Teste 2”); //Adiciona um item na pilha
Console.WriteLine(pilha.Pop()); //Retorna e remove automaticamente o último elemento inserido da pilha
pilha.Peek(); //Retorna o último elemento inserido na pilha sem remove-lo da lista

Dicionários

Os dicionários funcionam de modo semelhante as coleções com chaves que poderão ser usadas como índices. Estas chaves facilitam, e muito, a pesquisa de itens na lista.

SortedList

Esta classe é uma lista que se auto-ordena a medida que você vai inserindo os itens de acordo acordo com a chave que você esta passando como parâmetro.

SortedList listaOrdenada = new SortedList(); //Instancia a classe
listaOrdenada.Add(“Chave 2”, “Teste 1”); //Adiciona um item com a chave “Chave 2” e valor “Teste 1”
listaOrdenada.Add(“Chave 3”, “Teste 2”); //Adiciona um item com a chave “Chave 3” e valor “Teste 2”
listaOrdenada.Add(“Chave 1”, “Teste 3”); //Adiciona um item com a chave “Chave 1” e valor “Teste 3”

Para recuperar os itens da lista e verificar qual a ordem que o conteúdo esta na lista utilize o seguinte código.

foreach (DictionaryEntry item in listaOrdenada)
{
     Console.WriteLine(item.Value);
}

Como todo dicionário você poderá recuperar um item específico de acordo com a chave.

Console.WriteLine(listaOrdenada[“Chave 2”]);

Segue alguns métodos que são úteis para a manipulação da SortedList

Console.WriteLine(listaOrdenada.ContainsKey(“Chave 2”)); // Verifica se uma determinada chave existe na lista
Console.WriteLine(listaOrdenada.ContainsValue(“Teste 3”)); //Verifica se um determinado valor existe na lista
Console.WriteLine(listaOrdenada.GetByIndex(0)); //Retorna o valor de um determinado índice da lista
Console.WriteLine(listaOrdenada.GetKey(0)); //Retorna a chave de acordo com o índice
Console.WriteLine(listaOrdenada.IndexOfValue(“Teste 3”)); //Retorna o índice de acordo com o valor
Console.WriteLine(listaOrdenada.IndexOfKey(“Chave 2”)); //Retorna a índice de acordo com a chave

NameValueCollection

Semelhante a SortedList com algumas diferenças como: Especializada em strings, não possui ordenação automática, pode ser acessada tanto pela chave quanto por índice e você pode adicionar mais de um valor com a mesma chave.

NameValueCollection nomeValorLista = new NameValueCollection(); //Instancia a Classe
nomeValorLista.Add(“Nome 1”, “Valor 1”); //Adiciona um item
Console.WriteLine(nomeValorLista[0]); //Recupera um valor de acordo com o índice
Console.WriteLine(nomeValorLista[“Nome 1”]); //Recupera um valor de acordo com a chave

StringDictionary

StringDictionary é um dicionário especializado em strings que armazena seus valores em uma tabela hash. Utiliza o namespace System.Collections.Specialized e a forma de implementar é muito semelhante ao SortedList por isso vou demonstrar apenas como se instancia a classe.

StringDictionary stringDic = new StringDictionary();

ListDictionary

Semelhante ao StringDictionary mas não é especializado em strings e ela foi projetada para ter performance quando utilizar quando você manipular menos de 10 itens.

ListDictionary listDic = new ListDictionary();

HashTable

Semelhante ao ListDictionary porém com a recomendação de utiliza-la quando você manipular acima de 10 itens.

Hashtable hash = new Hashtable();

HybridDictionary

Como o próprio nome nos sugestiona, esta classe trabalha de forma hibrida. Ela funciona como um ListDictionary quando você tem menos de 10 itens e como um HashTable quando você passa desta quantidade.

HybridDictionary hybriDic = new HybridDictionary();

Coleções genéricas

Na minha opinião as coleções genéricas são uma nova versão das antigas coleções e dicionários. Você percebeu que, com exceção das coleções especializadas em strings, todos os itens que eu expliquei aceitam qualquer tipo de objeto dentro da lista, isto pode causar exceções na hora da conversão, queda de performance devido ao boxing e unboxing  e não queda na produtividade devido a não saber qual tipo de objeto irá retornar.

Para acabar com este problema, criou-se as coleções genéricas, que recebem um parâmetro informando qual tipo de objeto irá trabalhar dentro da lista.

Segue abaixo uma tabela de substituição.

Classe Genérica Classe não genérica
List<T> ArrayList, StringCollection
Dictionary<T,U> HashTable, ListDictionary, HybridDictionary, OrderedDictionary, NameValueCollection, StringDictionary
Queue<T> Queue
Stack<T> Stack
SortedList<T,U> SortedList
Collection<T> CollectionBase
ReadOnlyCollection<T> ReadOnlyCollectionBase

List<T>

Para instanciar uma List<T> do tipo genérico, você deve passar como parâmetro a classe definindo que a coleção será um determinado tipo e adicionar o namespace System.Collections.Generic. No exemplo abaixo estou dizendo que a minha lista irá apenas elementos do tipo int.

List<int> list = new List<int>();

Você irá perceber que, diferente das coleções explicadas anteriormente, esta lista irá apenas aceitar valores do tipo int e também só irá retornar valores deste mesmo tipo.

list.Add(1); //O método Add agora só aceita int como parâmetro.

E na hora de recuperar os valores eu posso esperar o tipo correto.

foreach (int numero in list)
{
    Console.WriteLine(numero.ToString());
}

Outra característica muito útil que as coleções genéricas têm é possibilidade de usar suas próprias classes para definir o tipo da lista.

List<Pessoa> list = new List<Pessoa>(); //No caso estou indicando para que seja criada uma lista da classe Pessoa.

SortedList<T,U>

Funciona da mesma forma que a SortedList não genérica que mantem sempre a coleção ordenada, porem você pode configurar o tipo de chave e valor que você irá utilizar. Segue abaixo um exemplo de implementação.

SortedList<int, Pessoa> listaOrdenada = new SortedList<int, Pessoa>(); //Instancio indicando que a chave será um int e o valor Pessoa
listaOrdenada.Add(3, new Pessoa(“Teste1”)); //Adiciono a chave 3 e o valor Pessoa(“Teste1”)
listaOrdenada.Add(1, new Pessoa(“Teste2”)); //Adiciono a chave 3 e o valor Pessoa(“Teste1”)
listaOrdenada.Add(2, new Pessoa(“Teste3”)); //Adiciono a chave 3 e o valor Pessoa(“Teste1”)
foreach (Pessoa pessoa in listaOrdenada.Values)
{
      Console.WriteLine(pessoa.ToString()); //Retorna o valor na ordem correta de acordo com a chave
}

Queue<T> – Fila genérica

Funciona da mesma forma que a classe Queue não genérica, porém você pode configurar qual o tipo de objeto estará dentro da sua lista. Segue abaixo como instancia-la.

Queue<Pessoa> fila = new Queue<Pessoa>();

Stack<T> – Pilha genérica

De semelhante modo.

Stack<Pessoa> pilha = new Stack<Pessoa>();

Dictionary<T,U>

O Dictionary genérico substitui todos dicionários demonstrados anteriormente.

Dictionary<int, Pessoa> dicGenerico = new Dictionary<int, Pessoa>(); //Instancio o dicionário com a chave do tipo int e valor do tipo Pessoa

Categorias:.NET Framework Etiquetas:

Manipulando arquivos no .NET

Vou mostrar como manipular arquivos dentro de sua aplicação. Irei escrever no artigo duas formas de fazer isso. A primeira é usando a classe File do namespace System.IO que é a maneira mais fácil de fazer isso e funciona muito bem para a maioria das situações. Agora se você precisa tratar arquivos grandes, compactação, arquivos em memória, criptografia e etc… utilize a segunda parte do artigo aonde eu apresento a classe Stream também do namespace System.IO.

File

Com classe File você pode ler arquivos, escrever, criptografar(de acordo com Windows), alterar alguns atributos e criar backups. Vamos direto aos exemplos com os métodos mais utilizados.

File.WriteAllBytes(“teste.txt”, new byte[] { byte.MaxValue }); //Sobrescreve um array de bytes no novo arquivo ou existente
File.WriteAllLines(“teste.txt”, new String[] { “Teste 1”, “Teste 2” }); //Sobrescreve o texto (array string) no novo arquivo ou existente
File.WriteAllText(“teste.txt”, “conteúdo total”); //Sobrescreve o texto no novo arquivo ou existente
File.AppendAllText(“teste.txt”, “conteúdo”); //Adiciona um texto ao arquivo existente ou cria um novo
File.Encrypt(“teste.txt”); //Criptografa o arquivo de acordo com as configurações do Windows
File.Decrypt(“teste.txt”); //Descriptografa o arquivo de acordo com as configurações do Windows
byte[] allBytes = File.ReadAllBytes(“teste.txt”); //Recupera todos os bytes do conteúdo do arquivo
string[] allLines = File.ReadAllLines(“teste.txt”); //Recupera um array de string contento todas as linhas do arquivo
string allText = File.ReadAllText(“teste.txt”); //Recupera todo o conteúdo do arquivo para dentro de uma string
File.SetAttributes(“teste.txt”, FileAttributes.Normal); //Configura o atributo do arquivo. Ex: Normal, Leitura, Sistema
File.SetCreationTime(“teste.txt”, DateTime.Now); //Configura a data de criação do arquivo
File.SetLastAccessTime(“teste.txt”, DateTime.Now); //Configura a ultima data que o arquivo foi acessado
File.SetLastWriteTime(“teste.txt”, DateTime.Now); //Configura a ultima data que o arquivo foi escrito
File.Replace(“teste.txt”, “teste1.txt”, “testebkp.txt”); //Substitui um arquivo pelo outro e faz uma cópia de segurança do segundo arquivo

Lembrando que a classe File trabalha diretamente com o arquivo, ou seja, cada a vez que você precisar escrever ou ler alguma coisa você precisa-rá chamar o arquivo novamente e executar a tarefa. Outro item importante é que a classe File trabalha sempre com o arquivo todo, por ex: nos métodos de Read o arquivo todo é lido de uma vez.

Stream

Utilizar a classe Stream é um pouco mais complexo, porém você terá maior controle sobre o arquivo. Stream é a classe base que permite você trabalhar diretamente com dados(Arquivo, Memória, Arquivo compactado e etc..) de forma seqüencial ou randômica. (Diferente do File que trabalha com o arquivo inteiro de uma vez).

Segue abaixo um diagrama demonstrando o diagrama de classe que representa a classe Stream e as classes que a implementam.

image 

Stream : Contém propriedades e métodos que serão usadas por todas as classes que a implementam. (Exemplo de métodos e propriedades compartilhada por todos os Streams: CanRead, Write, Position).

FileStream : Classe especializada no tratamento de arquivos.

BufferedStream : Classe especializada em prover performance por buffer de leitura e de escrita.

MemoryStream : Classe que permite você criar Streams diretamente na memoria.

DeflateStream : DeflateStream permite você compactar Streams utilizando o método de compressão Deflate.

GZipStream : GZipStream é semelhante ao DeflateStream porém com o método de compressão GZip.

UnmanagedMemoryStream : Fornece acesso a blocos não-gerenciados de memória.

 

Vamos explorar a classe base Stream. Todas as outras classes de Stream são baseadas nesta classe, isso quer dizer que, todos os métodos aqui serão utilizados pelas outras classes. Porém cada um dos outros Streams serão especializados em suas funções como descrevi acima. Como é uma classe abstrata, para instancia-la eu preciso determinar qual classe irá implementá-la. No caso estou usando um MemoryStream somente para exemplificar, no entanto você pode usar qualquer Stream para isso.

Stream _stream = new MemoryStream();

Segue abaixo algumas propriedades interessantes para você testar.

Console.WriteLine(_stream.CanRead); // Verifica se o Stream pode ser lido
Console.WriteLine(_stream.CanSeek); // Verifica se pode haver uma busca
Console.WriteLine(_stream.CanTimeout); // Verifica se o Stream tem um time-out
Console.WriteLine(_stream.CanWrite); // Verifica se o Stream pode ser lido
Console.WriteLine(_stream.Length); // Retorna o tamanho do Stream
Console.WriteLine(_stream.Position); //Recupera a posição do ponteiro dentro da memória

Para escrever e ler em um Stream você deve usar os métodos Write/WriteByte e Read/ReadByte. É muito importante entender o conceito do ponteiro, toda a escrita e leitura é feita a partir da posição que o ponteiro esta no momento. Segue abaixo um exemplo completo de escrita e leitura um Stream.

byte[] bytes = new byte[2] { byte.MaxValue, byte.MaxValue };
_stream.Position = 0; // Configura o ponteiro na posição 0
_stream.WriteByte(255); // Escreve o byte 255 (equivalente a ff) e passa o ponteiro para o fim da escrita
_stream.Write(bytes, 0, bytes.Length); // Recebe um array de bytes para escrever, 0 significa que não terá buffer, e o terceiro parâmetro indica quantos bytes devem ser escritos
_stream.Position = 0; //Retorna o ponteiro para posição inicial
while (_stream.Position != _stream.Length) //Executa o while enquanto o ponteiro não chegar no final
{
      Console.WriteLine( _stream.ReadByte()); //Le o byte e avança uma posição no ponteiro
}
_stream.Position = 0; // Configura o ponteiro na posição 0
Console.WriteLine(_stream.Read(bytes, 0, bytes.Length));// Recebe um array de bytes para ler, 0 significa que não terá buffer, e o terceiro parâmetro indica quantos bytes devem ser lidos

Abaixo irei explicar como se inicializa os Streams mais utilizados.

FileStream : Para inicializar o você precisa indicar o path do arquivo, como será o modo de utilização do arquivo, e qual tipo de permissão ele terá.

FileStream _fileStream = new FileStream(@”C:\Teste.txt”, FileMode.Open, FileAccess.Read); //Neste exemplo eu estou indicando que o arquivo C;\Teste.txt existe fisicamente e eu irei abri-lo para utilizar, e a permissão necessária para utilização do mesmo será somente para leitura.

Podemos inicializar o FileStream direto da classe File. Segue abaixo alguns exemplos.

FileStream fileStream = File.Create(“teste.txt”); // Cria um arquivo e associa ao FileStream
FileStream fileStream = File.Open(“teste.txt”, FileMode.Open); // Abre um arquivo e associa ao FileStream
FileStream fileStream = File.OpenRead(“teste.txt”); // Abre um arquivo e associa ao FileStream permitindo a leitura
FileStream fileStream = File.OpenWrite(“teste.txt”); // Abre um arquivo e associa ao FileStream permitindo a escrita

MemoryStream :  Como o MemoryStream é baseado apenas na memória sua inicialização é muito simples.

MemoryStream _memoryStream = new MemoryStream();

GzipStream : O Stream de compactação GzipStream precisa que você indique se o processo vai ser de compactação ou de descompactação e também indique qual Stream vai ser compactado ou descompactado.

GZipStream _gZipStream = new GZipStream(_fileStream, CompressionMode.Compress); //Neste exemplo estou indicando que vou compactar um FileStream

 

Leitura e escrita

Você pode usar o exemplo de escrita e leitura da classe base Stream que eu demonstrei para todas as classes que implementam a classe Stream, porém existe algumas classes especializadas para executar isso. Segue abaixo um diagrama que demonstra toda a estrutura completa de classes para leitura e escrita em um Stream.

image

 

TextWriter : Classe base para todas classes de escrita com exceção da BinaryWriter.

StreamWriter : Classe especializada na escrita em Stream.

HtmlTextWriter : Classe especializada na escrita de Html.

StringWriter : Classe especializada na escrita de strings.

BinaryWriter : Classe especializada na escrita de bytes.

TextReader : Classe base para todas classes de leitura com exceção da BinaryReader.

StreamReader : Classe especializada na leitura em Stream.

StringReader : Classe especializada na leitura de strings.

BinaryReader : Classe especializada na leitura de bytes.

 

StreamWriter

A classe StreamWriter herda as funcionalidade da classe TextWriter. Ela permite você escrever no Stream. Abaixo segue um exemplo de como utilizar.

StreamWriter sw = new StreamWriter(_fileStream); //Inicializa um StreamWriter. Utilizei um FileStream que aponta para um arquivo físico
sw.Write(“teste”); //Escreve no StreamWriter uma string que você passar como parâmetro
sw.WriteLine(); //Escreve uma quebra de linha no StreamWriter
sw.Flush(); // Escreve no Stream configurado (no caso um FileStream representando um arquivo) e limpa o buffer do StreamWriter
sw.AutoFlush = false; // Você pode utilizar o auto flush para indicar o flush será executado automaticamente cada vez que você chamar o método Write ou WriteLine do StreamWriter

Podemos inicializar o StreamWriter diretamente da classe estática File.

StreamWriter sw = File.CreateText(“teste.txt”); //Cria ou abre um arquivo físico e associa com o StreamWriter
StreamWriter sw = File.AppendText(“teste.txt”); //Associa um arquivo existente e adiciona o conteúdo que será escrito no StreamWriter com o conteúdo do arquivo

StreamReader

StreamReader é a classe responsável por ler conteúdo dos Stream e herda da classe TextReader. Abaixo eu demonstrarei com usá-la.

StreamReader sr = new StreamReader(_fileStream); //Inicializa o StreamReader. Utilizei um FileStream que aponta para um arquivo físico
Console.WriteLine(sr.ReadLine()); //Le a linha em que o ponteiro esta no momento e adianta o ponteiro para a próxima linha
Console.WriteLine(sr.ReadToEnd()); //Le todo o FileStream a partir do posição atual do ponteiro a avança o ponteiro para o final
Console.WriteLine(sr.EndOfStream); //Verifica se o ponteiro está no final do FileStream

Liberando recursos

É uma boa prática chamar o mesmo close para liberar recursos do sistema quando estamos trabalhando com memória não-gerenciável como por exemplo Streams, Writer e Reader.

_fileStream.Close();
sw.Close();
sr.Close();

 

E chegamos ao fim de mais um artigo. Como este assunto é muito vasto, decidi escolher os itens mais comuns de serem utilizados para demonstrar aqui, então por isso que algumas classes eu não descrevi como implementa-las.

Espero que tenham gostado.

Categorias:.NET Framework Etiquetas:,
%d bloggers gostam disto: