Arquivo

Archive for the ‘.NET Framework’ Category

Monitorando Pastas

Quantas vezes precisamos implementar um looping para verificar se um determinado arquivo foi copiado para uma pasta, ou quanta vezes temos que monitorar a alteração do conteúdo de um documento ou se o mesmo foi apagado. Este processo exige um esforço muito grande além de diminuir a performance de nosso sistema devido a quantidade de loopings que temos que fazer.

Para resolver este problema podemos utilizar a classe FileSystemWatcher do namespace System.IO. Com ela nós podemos configurar uma determinada pasta para ser monitorada e quando algum evento acontecer nós seremos avisados.

Para iniciar o monitoramento você só precisa configurar duas coisas.

FileSystemWatcher monitorPastas = new FileSystemWatcher(@”C:\Teste”); //Instancia a classe configurando a pasta que será monitorada
monitorPastas.EnableRaisingEvents = true; //Habilita o monitoramento

Você também pode fazer alguma configurações interessantes

monitorPastas.Filter = “*.txt”; //Nesta string você pode filtrar quais arquivos você deseja monitorar
monitorPastas.IncludeSubdirectories = true; //Booleano indicando se subdiretórios serão monitorados ou não           
monitorPastas.Path = @”C:\Teste”; //Altera o path que será monitorado
monitorPastas.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;  //Configura quais tipos de alterações deverão ser monitoradas

Para receber as notificações do monitoramento e trata-los você deve associar um evento específico a um método criado por você respeitando as assinatura do delegate.

Segue abaixo os quatros eventos possíveis que você pode monitorar.

monitorPastas.Changed += new FileSystemEventHandler(monitorPastas_Changed); //Alterações
monitorPastas.Created += new FileSystemEventHandler(monitorPastas_Created); //Criações
monitorPastas.Deleted += new FileSystemEventHandler(monitorPastas_Deleted); //Exclusões
monitorPastas.Renamed += new RenamedEventHandler(monitorPastas_Renamed); //Renomeações

Segue abaixo os quatros métodos que você deve criar para poder tratar esses eventos.

void monitorPastas_Renamed(object sender, RenamedEventArgs e)
{
    Console.WriteLine(e.ChangeType + ” de ” + e.OldFullPath + ” para ” + e.Name);
}
void monitorPastas_Deleted(object sender, FileSystemEventArgs e)
{
   Console.WriteLine(e.ChangeType + “: ” + e.FullPath);
}
void monitorPastas_Created(object sender, FileSystemEventArgs e)
{
   Console.WriteLine(e.ChangeType + “: ” + e.FullPath);
}
void monitorPastas_Changed(object sender, FileSystemEventArgs e)
{
   Console.WriteLine(e.ChangeType + “: ” + e.FullPath);
}

Espero que com essa dica vocês tenham a possibilidade de melhorar a performance dos seus sistemas.

Categorias:.NET Framework Etiquetas:

Manipulando Path

O .NET Framework nos disponibiliza uma classe pouco utilizada por não ser conhecida, porém muito útil para tratarmos path, nome de arquivos, extensões e etc..

Dentro no namespace System.IO existe uma classe estática chamada Path. Esta classe acaba com aquele quantidade de loopings que fazíamos toda vez que precisamos verificar um extensão de arquivo ou então os replaces para retirar os caráteres separados de um path. A classe permite manipular um path de maneira muito simples e útil. Sem mais delongas segue abaixo alguns exemplos com seus devidos comentários.

Console.WriteLine(Path.ChangeExtension(@”C:\Teste.ttt”, “txt”)); //Altera a extensão do arquivo no path
Console.WriteLine(Path.Combine(@”C:\Teste”, @”SubTeste\sad.txt”)); //Concatena dois path
Console.WriteLine(Path.DirectorySeparatorChar); //Retorna o caracter separador de diretórios
Console.WriteLine(Path.GetDirectoryName(@”C:\Windows\win.ini”)); //Retorna o diretório do path
Console.WriteLine(Path.GetExtension(@”C:\Windows\win.ini”)); //Retorna a extensão do arquivo
Console.WriteLine(Path.GetFileName(@”C:\Windows\win.ini”)); //Retorna o nome completo do arquivo
Console.WriteLine(Path.GetFileNameWithoutExtension(@”C:\Windows\win.ini”) ); //Retorna o nome do arquivo sem extensão
Console.WriteLine(Path.GetFullPath(@”win.ini”)); //Retorna o path completo do arquivo
Console.WriteLine(Path.GetInvalidFileNameChars()); //Disponibiliza todos caracteres inválidos para criar um nome de arquivo
Console.WriteLine(Path.GetInvalidPathChars()); //Disponibiliza todos os caracteres inválido para criar uma pasta
Console.WriteLine(Path.GetPathRoot(@”C:\Windows\win.ini”)); //Retorna o drive do path
Console.WriteLine(Path.GetRandomFileName()); //Gera um nome de arquivo randômico
Console.WriteLine(Path.GetTempFileName()); //Retorna um nome de arquivo randômico dentro da pasta temporária
Console.WriteLine(Path.GetTempPath()); //Retorna o path completo da pasta temporária
Console.WriteLine(Path.HasExtension(@”C:\Windows\win.ini”)); //Verifica se o arquivo do path tem extensão
Console.WriteLine(Path.VolumeSeparatorChar); //Retorna o caracter separador de volumes

Espero que com esta dica o seu trabalho com path seja facilitado.

Categorias:.NET Framework Etiquetas:

Sistemas de Arquivo no .NET

O .Net Framework tem classes que nos permitem criar, deletar, navegar, e etc.. arquivos e pastas do Windows. Podemos até criar um Windows Explorer Genérico com todas essas funcionalidades e outras mais.

Todas essas features ficam dentro do namespace System.IO. Abaixo explicarei algumas das possiblidades que o .Net disponibiliza para manipulação de sistema de arquivos.

Manipulando Drives

A classe DriveInfo representa um drive (ex: C:\, CDROM, USB, etc.). Para instanciá-la a partir de um drive existente basta você passar o nome do drive no construtor padrão da classe.

DriveInfo drive = new DriveInfo(@"C:\");

Dentro do objeto drive que instanciamos no exemplo anterior temos alguns métodos e propriedades interessantes para ser usadas.  Segue abaixo alguns exemplos:

drive.Name; //Retorna o nome do Drive
drive.AvailableFreeSpace; //Total de espaço disponível
drive.DriveFormat; //Se ele é NTFS ou FAT
drive.DriveType; //Se ele é CDROM, HD, USB e etc..
drive.TotalSize; //Tamanho total

Para retornar todos os drives do computador utilize o seguinte exemplo:

foreach (DriveInfo drive in DriveInfo.GetDrives())
{
      Console.WriteLine(drive.Name);
}

Pastas ou Diretórios

De modo semelhante aos drives, você pode utilizar a classe DirectoryInfo para manipular pastas ou diretórios. Para instanciar utilize:

DirectoryInfo diretorio = new DirectoryInfo(@"C:\"); ou  DirectoryInfo diretorio = new DirectoryInfo(@"C:\MinhaPasta");

Segue abaixo alguns métodos e propriedades úteis:

diretorio.Name; //Retorna o nome da Pasta
diretorio.CreationTime.ToShortDateString(); //Data de criação
diretorio.Exists; //Verifica se o diretório existe fisicamente
diretorio.FullName; //Path completo
diretorio.Create();//Cria o diretório fisicamente
diretorio.Delete();//Apaga o diretório
diretorio.MoveTo(@"C:\NovoDiretorio\"); //Move o diretório para outro path

Para retornar todos os sub-diretórios do objeto diretório utilize:

foreach (DirectoryInfo subdiretorio in diretorio.GetDirectories())
{
      Console.WriteLine(subdiretorio.Name);
}

Para retornar os arquivos de sistema:

foreach (FileSystemInfo arquivoSistema in diretorio.GetFileSystemInfos())
{
      Console.WriteLine(arquivoSistema.Name);
}

E para retornar todos os arquivos:

foreach (FileInfo arquivo in diretorio.GetFiles())
{
     Console.WriteLine(arquivo.Name);
}

Pastas ou Diretórios 2

Existe também a classe Diretory, que trabalha de forma estática e de modo muito semelhante a classe DirectoryInfo. Segue abaixo algumas métodos úteis da classe directory para você obter informações.

Console.WriteLine(Directory.Exists(@"C:\Teste")); //Verifica se o diretório existe fisicamente
Console.WriteLine(Directory.GetCreationTime(@"C:\Teste")); //Retorna a data de criação do diretório
Console.WriteLine(Directory.GetCurrentDirectory()); //Retorna o diretório atual da aplicação

Para manipulação, a classe contem os seguintes métodos.

Directory.CreateDirectory(@"C:\Teste"); //Cria um diretório
Directory.Move(@"C:\Teste", @"C:\Teste2"); //Move o diretório
Directory.Delete(@"C:\Teste2"); //Delete a o diretório

Com a classe Directory você pode retornar um array de strings contendo todos os arquivos ou diretórios contido dentro de um path.

//Retorna todos os diretórios
foreach (string diretorio in Directory.GetDirectories(@"C:\"))
{
       Console.WriteLine(diretorio);
}
//Retorna todos os arquivos
foreach (string arquivo in Directory.GetFiles(@"C:\"))
{
       Console.WriteLine(arquivo);
}

Arquivos

Para manipular arquivos é da mesma forma, porem utilizando a classe FileInfo:

FileInfo arquivo = new FileInfo("teste.txt");    //Por Default a pasta padrão é ~\bin\debug
FileInfo arquivo = new FileInfo(@"C:\teste.txt");  //O construtor também aceita o path completo

Segue abaixo alguns métodos úteis:

Console.WriteLine(arquivo.Name); //Retorna o nome da Pasta
Console.WriteLine(arquivo.CreationTime.ToShortDateString()); //Data de criação
Console.WriteLine(arquivo.Exists); //Verifica se o diretório existe fisicamente
Console.WriteLine(arquivo.FullName); //Path completo

Também é possível manipular o arquivo dentro do FileInfo

arquivo.Create(); //Cria um arquivo físico baseado no FileInfo
arquivo.CreateText(); //Cria um StreamWriter e um novo arquivo para ser escrito
arquivo.CopyTo(@"c:\teste2.txt"); // Cria uma cópia do arquivo físico
arquivo.MoveTo(@"c:\teste2.txt"); // Move o arquivo físico para um novo arquivo
arquivo.Delete(); // Deleta o arquivo físico

Arquivos2

Outra forma de você manipular arquivos é utilizando a classe File. Ela tem funcionalidade muito semelhantes a classe FileInfo, porém trabalha de forma estática, ou seja, sem precisar instanciar o objeto.

File.Create(@"C:\teste.txt"); //Cria um arquivo físico
File.CreateText(@"C:\teste.txt"); //Cria um StreamWriter e um novo arquivo para ser escrito
File.Copy(@"C:\teste.txt", @"C:\teste2.txt"); // Cria uma cópia do arquivo físico
File.Move(@"C:\teste.txt", @"C:\teste3.txt"); // Move o arquivo físico para um novo arquivo
File.Delete(@"C:\teste3.txt"); //Deleta o arquivo físico
Console.WriteLine(File.Exists(@"C:\teste2.txt")); //Verifica se o arquivo existe fisicamente

E por enquanto é isso pessoal. Escreverei mais sobre sistemas de arquivo no .Net no meu próximo post.

Categorias:.NET Framework

Enviando E-mail com o .NET

8 de Outubro de 2010 1 comentário

Hoje vou escrever sobre como criar e enviar um e-mail utilizando o .NET. Vamos direto ao assunto.

Criando um objeto MailMessage

No .NET você precisa instanciar a classe MailMessage para criar o seu e-mail. Para instanciá-la você deve incluir o namespace System.Net.Mail que provê uma série de features para este contexto.

No exemplo abaixo você verá como instanciar a classe MailMessage já configurando o remetente, destinatário, Assunto e o conteúdo.

MailMessage email = new MailMessage(remente@servidor.com, destinatario@servidor.com, “Assunto”, “Conteúdo”);

Você também pode utilizar o construtor padrão e configurar as propriedades posteriormente. Perceba que eu utilizei a classe MailAdress para adicionar o destinatário e o remetente.

MailMessage email = new MailMessage();
email.From = new MailAddress(“
remente@servidor.com“, “Remetente”);
email.To.Add(new MailAddress(“
destinatario@servidor.com“, “Destinatário”));
email.Subject = “Assunto”;
email.Body = “Conteúdo”;
email.Priority = MailPriority.Normal;

Anexando arquivos ao e-mail

Para anexar um arquivo qualquer no seu e-mail o seu objeto de e-mail criado e adicione um objeto “Attachment” contento o caminho para o arquivo.

email.Attachments.Add(new Attachment(@”C:\Pasta\arquivo.txt”));

Você também pode utilizar as configurações do “Attachment” para anexar arquivos do tipo MIME direto da memória. mas para isso você precisa ter carregado um objeto “Stream” contendo o seu arquivo.

Stream arq= new FileStream(@”C:\ebook.pdf”, FileMode.Open, FileAccess.Read);
email.Attachments.Add(new Attachment(arq, “livro.pdf”, MediaTypeNames.Application.Pdf));

E-mail com formato HTML

A classe MailMessage também permite que você crie o corpo do e-mail como html ao invés de um simples texto. Segue abaixo o exemplo.

email.Body = “<html><body>Este conteúdo é um html</body></html>”;
email.IsBodyHtml = true;

Alguns leitores de e-mail podem não ler e-mails quando o corpo do mesmo está configurado como html. Para isso você utiliza a classe AlternateView. Basta você criar uma visualização html e uma para um texto simples. Abaixo eu demonstro como fazer isso.

AlternateView visualizacaoHtml= AlternateView.CreateAlternateViewFromString(“Meu conteúdo html”, null, MediaTypeNames.Text.Html);
AlternateView visualizacaoTexto= AlternateView.CreateAlternateViewFromString(“Meu texto simples”, null, MediaTypeNames.Text.Plain);

email.AlternateViews.Add(visualizacaoHtml);
email.AlternateViews.Add(visualizacaoTexto);

E se você quiser incluir uma imagem dentro do conteúdo html que não seja um anexo utilize a classe LinkedResource. Preste atenção no src da imagem no conteúdo html e na propriedade ContentID do objeto LinkedResource.

AlternateView visualizacaoHtml = AlternateView.CreateAlternateViewFromString(“<html><body><img src=\”cid:Foto\”></body></html>”, null, MediaTypeNames.Text.Html);
LinkedResource recursoLinkado = new LinkedResource(“fotoSalva.jpg”, MediaTypeNames.Image.Jpeg);
recursoLinkado.ContentId = “Foto”;
visualizacaoHtml.LinkedResources.Add(recursoLinkado);

Enviando o e-mail criado

Para enviar o e-mail criado você irá utilizar uma classe chamada SmtpClient que também esta no namespace System.Net.Mail. Você apenas precisa ter o endereço do seu servidor SMTP, o resto o .Net fará pra você.

SmtpClient clienteSmtp = new SmtpClient(“smtp.servidor.com”);
clienteSmtp.Send(m);

Para habilitar envio com ssl utilize a propriedade EnableSsl.

clienteSmtp.EnableSsl = true;

Para configurar o envio de e-mail utilizando as credenciais default habilite a propriedade UseDefaultCredentials.

clienteSmtp.UseDefaultCredentials = true;

Para definir uma nova credencial adicione o namespace “System.Net” e configure a propriedade Credentials com um objeto NetworkCredential.

clienteSmtp.Credentials = new NetworkCredential(“usuário”, “senha”);

Você também pode utilizar a credencial que esta no cache do usuário.

clienteSmtp.Credentials = CredentialCache.DefaultNetworkCredentials;

Para configurar um TimeOut para o envio de e-mail utilize a propriedade Timeout.

clienteSmtp.Timeout = 10;

Enviando o e-mail de modo assíncrono

Como o envio de e-mail geralmente é um processo lento, pode acontecer de sua aplicação ficar esperando o envio para poder continuar o processamento. Podemos evitar isso utilizando o envio assíncrono. Para utilizar o envio assíncrono, você precisa associar um método (que tenha os parâmetros object e AsyncCompletedEventArgs)  ao evento SendCompleted e enviar o e-mail utilizando o método SendAsync.

clienteSmtp.SendCompleted +=new SendCompletedEventHandler(EnvioCompleto);
clienteSmtp.SendAsync(m);

static void EnvioCompleto(object sender, AsyncCompletedEventArgs e)
{ }
   

Para cancelar o envio de e-mail assíncrono basta chamar o método SendAsyncCancel

clienteSmtp.SendAsyncCancel;

É isso ai pessoal, espero que este artigo ajude vocês implementarem o envio de e-mail em suas aplicações.

Francisco Gonçalves

Categorias:.NET Framework

Desvendando o Globalization do .NET

 O .NET contem recursos que possibilitam que sua aplicação trabalhe de forma condizente com uma linguagem/cultura específica sem que você precise refazer o código quando você quiser mudar de cultura.

Abaixo eu descreverei várias funcionalidade do Globalization que podemos utilizar em nossos projetos. Recomendo ler os itens na seqüência, pois os assuntos estão organizados por pré-requisitos de aprendizado.

Verificando qual cultura sua aplicação está configurada

Por padrão sua aplicação assume as configurações de cultura que seu Windows está configurado. Para verificar isso utilize o código abaixo. Para utiliza-lá você precisa incluir o namespace System.Threading na sua aplicação.

Thread.CurrentThread.CurrentCulture.ToString();

No meu caso este exemplo retorna “pt-BR” aonde “pt”(Português) que define as configurações da linguagem e “BR” (Brasil) define as configurações regionais, específica de cada país.

No código abaixo você pode verificar a configuração que o Resource Manager esta configurado.

Thread.CurrentThread.CurrentUICulture.ToString();

Alterando a configurações regionalização da sua aplicação

Para alterar as configurações de sua aplicação, primeiro você precisa conhecer a Classe CultureInfo. É ela que Fornece informações sobre uma cultura específica. Ex.: Calendário, Ordenação e formatação de datas e horas. Para utiliza-lá você precisa incluir o namespace System.Globalization na sua aplicação.

Segue abaixo o código para realizar a alteração.

Thread.CurrentThread.CurrentCulture = new CultureInfo(“en-US”);

Neste caso estou alterando a minha aplicação para utilizar as configurações “en”(Inglês) “US(Estados Unidos)”. Você também pode alterar o CurrentUICulture da mesma forma.

Você pode verificar a diferença de formatação de cada cultura em relação a data utilizando o seguinte código para cada configuração que você escolher. Utilizando um projeto console.

Console.WriteLine(DateTime.Now.ToString());

Utilizando culturas diferentes no método ToString()

Para configurar a cultura específica apenas na saída string de uma propriedade utilize o código abaixo.  Neste caso estou alterando para Inglês-Estados Unidos.

Console.WriteLine(DateTime.Now.ToString(new CultureInfo(“en-US”)));

Listando todas as culturas registradas no Framework

A classe CultureInfo tem um método chamado GetCultures que retorna um coleção de CultureInfo registrados no Framework. Este método aceita um CultureTypes como parâmetro que funciona como um filtro. Para retornar todas as culturas registradas utilize o seguinte código.

foreach (CultureInfo item in CultureInfo.GetCultures(CultureTypes.AllCultures))
               Console.WriteLine(item.ToString());

Recuperando as configurações de uma cultura específica

A classe CultureInfo possui uma série propriedades que permitem você recuperar informações interessantes sobre uma configuração. São elas a NumberFormat e a DateTimeFormat. Dentro de cada uma delas você tem configurações específicas para número e Data. Por exemplo: NumberDecimalSeparator e DateSeparator.

Abaixo um exemplo de utilização.

CultureInfo cultura = new CultureInfo(“pt-BR”);

cultura.NumberFormat.NumberDecimalSeparator;

Construindo e registrando sua própria cultura

Você pode construir culturas personalizadas para ser usadas por todas suas aplicações.

Primeiro adicione o assembly sysglobl.dll (que na minha maquina fica na pasta C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sysglobl.dll).

Utilize a classe CultureAndRegionInfoBuilder para construir a nova cultura.

CultureAndRegionInfoBuilder construtorCultura = new CultureAndRegionInfoBuilder(“pt-K1”, CultureAndRegionModifiers.None);

Carregue sua nova cultura baseada em outra.

construtorCultura.LoadDataFromCultureInfo(new CultureInfo(“pt-BR”));   construtorCultura.LoadDataFromRegionInfo(new RegionInfo(“BR”));

Altere as propriedades que você deseja personalizar. Existem muitas propriedades, então, segue abaixo apenas um exemplo.

construtorCultura.IsMetric = false;

Para registrar utilize:

construtorCultura.Register();

Agora você já pode utilizar esta cultura em todas as suas aplicações, basta apenas instancia-lá chamando o CultureInfo(“pt-K1”).

E para retirar o registro utilize:

construtorCultura.Unregister(“pt-K1”);

Ordenação de acordo com a cultura

Um conceito muito interessante sobre culturas no .Net é que a mesma influencia na ordenação de caracteres. O caractere “Æ” vem antes “A” na nossa ordenação comum, mas em alemão é diferente, ela vem após a letra “A”.  Teste o seguinte exemplo com a cultura “pt-BR” e com a “da-DK”. e verifique que a ordenação automática do .Net mudou a seqüencia do array.

string[] caracteres= new string[] { “A”, “Æ” }; Array.Sort(caracteres);

Pesquisa de string de acordo com a cultura

A pesquisa de index de uma string (“texto”.IndexOf) pode trabalhar de forma diferente para cada cultura. Por exemplo:

Com a cultura “pt-BR”, se você pesquisar o caractere “Æ” dentro de uma string, ele retornará tanto os caracteres “Æ” quanto “AE”,  e a mesma coisa quando você estiver procurando o caractere “AE” ele irá retornar tanto o “Æ” quando “AE”. Já com a cultura “da-DK” é diferente, quando você pesquisar por “Æ” só retornará “Æ” e quando você pesquisar por “AE” só retornará “AE”. Faça um teste com o seguinte código abaixo configurando cada teste em uma cultura diferente.

“Æ”.IndexOf(“Æ”); “Æ”.IndexOf(“AE”);

“AE”.IndexOf(“Æ”); “AE”.IndexOf(“AE”);

Para contornar esta situação podemos declarar que as comparações serão independentes da cultura utilizando os seguintes métodos.

“Æ”.IndexOf(“Æ”, StringComparison.InvariantCulture); ou  Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

Comparação de acordo com a cultura

A comparação de strings também se comporta diferente em cada cultura. Faça o seguinte teste na cultura “pt-BR” e “tr-TR”

string.Compare(“teste”, “TESTE”, true);

Você pode verificar que mesmo mesmo indicando com o “true” que a comparação a ser feita é case-insensitive em “tr-TR”(Turquia-Turco) o retorno é falso indicando que as strings são diferentes. Já em “pt-BR” o retorno me diz que a comparação é verdadeira.

Aprendi muito escrevendo este artigo, espero que gostem.

Fontes:

http://msdn.microsoft.com/pt-br/library/system.globalization.cultureinfo(VS.90).aspx

http://msdn.microsoft.com/pt-br/library/1ztca10y(VS.90).aspx

http://msdn.microsoft.com/pt-br/library/system.threading.thread.currentuiculture(VS.90).aspx

http://www.microsoft.com/learning/en/us/Book.aspx?ID=12915&locale=en-us

Categorias:.NET Framework
%d bloggers like this: