Boa Ideia
[ Everton Coimbra de Arajo e Giuvane Conti ]
.Net 37 Primeiros passos com o namespace System.IO dando a compreender com ainda
[ Fbio Rosa ] mais facilidade o contedo desta
edio. Ser um prazer contar com
sua companhia! Confira abaixo o
que teremos nesta revista:
Expediente Editorial
EDITORIAL
J
faz bastante tempo que a Web 2.0 foi lanada, mas, porque no pensarmos
que antes no existia uma forma de interagir com os visitantes? Atualmente,
sempre que visitamos uma pgina, pensamos logo em ir visualizar os coment-
rios da mesma. Um exemplo notrio de Web Site que utiliza recursos da Web 2.0 so
os Blogs. Desta forma, que tal aprender a criar um blog no ASP.NET? Vladimir Rech
mostra na prtica cada passo.
Alm desse tema, tambm temos outro assunto que sempre ser importante, exe-
Ano 3 - 25 Edio 2012 - ISSN 2179624-6 cutar tarefas na sua aplicao sem depender de outras. Um exemplo muito comum
quando sua aplicao trava quando voc gera um relatrio no sistema (vendas do
ms, por exemplo). Neste caso, por que no colocar este relatrio em uma Thread?
esse o objetivo do artigo Iniciando com Threads no C#.
Para finalizar, temos o artigo do Fbio Rosa, que demonstra na prtica como trabalhar
Corpo Editorial
com diretrios e arquivos utilizando a biblioteca System.IO do .NET Framework. Seja
ASP.NET ou Windows Forms, a manipulao dos mesmos sempre ser necessrio.
Jornalista Responsvel
Kaline Dolabella - JP24185
Na Web
www.devmedia.com.br/revista-easy-dotnet-magazine
Rafael Silva
rafael@rlsystem.com.br
Editor Chefe da .net Magazine e Easy .net Magazine
http://www.rlsystem.com.br
Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo para o atendimento ao leitor. Se voc tiver algum
twitter.com/rafaellealsilva
problema no recebimento do seu exemplar ou precisar de algum esclarecimento sobre assinaturas,
exemplares anteriores, endereo de bancas de jornal, entre outros, entre em contato com:
www.devmedia.com.br/central
(21) 3382-5038
Fale com o Editor!
muito importante para a equipe saber o que voc est achando da revista: que tipo de artigo voc
Publicidade gostaria de ler, que artigo voc mais gostou e qual artigo voc menos gostou. Fique a vontade para
entrar em contato com os editores e dar a sua sugesto!
Para informaes sobre veiculao de anncio na revista ou no site e para fechar parcerias ou aes
especficas de marketing com a DevMedia, entre em contato com: Se voc estiver interessado em publicar um artigo na revista ou no site .NET Magazine, entre em
contato com os editores, informando o ttulo e mini-resumo do tema que voc gostaria de publicar:
Cristiany Queiroz
publicidade@devmedia.com.br Rafael Silva - Editor da Revista
rafael@rlsystem.com.br
Desenvolvendo um
blog com ASP.NET
Parte 1
Este artigo faz parte de um curso Resumo DevMan
De que se trata o artigo:
A
t a chegada do Framework .NET, o desen- Este artigo trata dos recursos nativos no ASP.NET (como gridview, Da-
volvimento de aplicaes Web baseava-se em taGrid, etc) para a criao de aplicaes Web utilizando os recursos de
projetos desenvolvidos em plataformas como Web Forms. A ideia bsica criar um sistema de blog.
PHP ou ASP clssico, onde a interface era criada usando
editores HTML e o cdigo da regra de negcios escrito Em que situao o tema til:
juntamente com a interface. O tema til para os desenvolvedores conhecerem os principais
O problema principal no desenvolvimento Web no a recursos nativos que existem na plataforma .NET, como os controles
separao entre interface de usurio e regras de negcio, de WebForms: TextBox, GridView etc. Desta forma, ser possvel criar
mas entender os detalhes que envolvem o gerenciamento qualquer tipo de aplicao Web.
de uma aplicao baseada numa arquitetura cliente-
servidor. Um destes detalhes baseia-se no fato de que Desenvolvendo um blog com ASP.NET Parte 1:
do lado do cliente (usurio da aplicao) existe pouco Desenvolver aplicaes ASP.NET usando Web Forms a maneira mais
ou nenhum controle do que est acontecendo e assim, prtica de criar projetos que sero executados em browsers, visto que
torna-se necessrio gerenciar o estado da pgina para atravs do mesmo voc possui um conjunto de controles prontos para
poder enviar os dados corretos. Considere tambm a serem utilizados, gerando uma grande produtividade. Para poder explorar
grande diversidade de browsers existentes e que cada os recursos do ASP.NET, este artigo vai considerar a utilizao dos mesmos
um possui particularidades na renderizao do HTML, em um projeto para gerenciar blogs de vrios usurios.
comportamento do JavaScript etc. Nestes blogs, o usurio poder enviar suas publicaes "baseadas
Parte destes problemas (no .NET) so resolvidos de em texto puro para simplificar algumas tarefas" alm de gerenciar os
maneira bem simples, atravs de server controls, que dados do blog.
so componentes que podem ser destinados a montar
uma interface com o usurio, tais como TextBox, Labels,
Combo Box entre outros, alm de controles no visuais e, rapidamente comearam a aparecer pginas muito pesadas que
destinados a realizar tarefas de validaes, por exemplo. tentavam recriar nos browsers o mesmo ambiente de aplicaes
Todos estes componentes podem ser facilmente mani- desktop. Isso um erro, porque o browser um ambiente distinto
pulados atravs das caixas de ferramentas do Visual do desktop, os recursos so limitados e, ainda que seja possvel
Studio e do editor de propriedades. construir interfaces com um layout rico, certos cuidados precisam
Um dos aspectos mais importantes e tambm mais cri- ser tomados, como evitar a utilizao excessiva de controles, com-
ticados do ASP.NET o recurso de criao de Web Forms. ponentes desnecessrios e validaes interminveis.
Este consiste de server controls aninhados em uma tag Considerando ainda o ASP.NET, a sua principal vantagem que
<form>, ou seja, voc pode fazer o design de um Web possvel definir a interface com o usurio utilizando um arquivo
Form como faria em uma aplicao Windows Forms, dada ASPX que possui marcaes HTML para os server controls, tags
a sua facilidade de manipulao. Mas, muitos excessos so HTML, alm de suporte a JavaScript e CSS. Alm disso, utiliza
cometidos por alguns desenvolvedores menos preparados um arquivo separado para escrever o cdigo C# (ou VB.NET)
Validadores
Uma das boas prticas no desenvolvimento de qualquer tipo de
software que antes que os dados sejam persistidos no banco, estes
possam ser validados para evitar problemas, tais como:
1. Estouro de capacidade de armazenamento de campos em ta-
belas. Por exemplo, campos string (varchar no SQL Server) que
tenham tamanho menor do que o comprimento do texto que esteja
sendo enviado ir causar um erro na aplicao.
2. Os tipos de dados podem ser incompatveis. O usurio pode
ter digitado um valor errado em um campo numrico, uma data
no formato errado.
3. Dados mais complexos podem estar incorretos, tais como endere-
os de e-mail que precisam sempre respeitar um formato. O usurio
desavisado pode acabar enviando um endereo incorreto.
4. Validaes para manter regras da aplicao. Pode ser que no
Figura 2. Usando a visualizao Split do Visual Studio
seu projeto no possam haver nomes repetidos ou endereos de
e-mail repetidos, por exemplo.
Ao utilizar esses cdigos JavaScript, estes so executados sem
que seja necessrio o envio de dados para o servidor. Assim, em Estes tipos de verificao podem ser feitos de diversas maneiras,
casos com validaes ou interaes com o usurio, interessante tanto usando cdigo escrito com C# no code behind da aplicao
usar JavaScript. como em JavaScript.
Uma aplicao tpica pedir a confirmao de alguma ao, por O uso do cdigo escrito com C# apresenta a desvantagem de
exemplo, ao clicar em um boto para enviar dados para o servidor. exigir uma validao no servidor e, consequentemente, espera
Veja um exemplo de implementao a seguir, onde o cdigo do usurio nesta tarefa. J a utilizao do JavaScript pode tornar
de confirmao em JavaScript adicionado ao corpo de uma a validao insegura, visto que o usurio pode desativ-lo em
pgina ASPX. qualquer navegador. Na prtica, o ideal utilizar os dois, sim-
plesmente pelo fato que a utilizao do JavaScript permite que as
<html xmlns=http://www.w3.org/1999/xhtml> informaes sejam validadas sem a necessidade da pgina ir at
<head runat=server>
<title>BlogEngine - Gerenciador de Blogs</title> o servidor e, caso o usurio desative o Javascript, o mesmo seria
<script language=javascript> automaticamente validado pelo servidor, atravs do C#.
function confirmacao(msg) { return confirm(msg); }
Para contornar este problema, o ASP.NET disponibiliza um
</script>
</head> conjunto de controles chamado Validators, que podem ser encon-
trados no Visual Studio, na aba Validation (Figura 3). Alm disso,
Ou usando arquivos com a extenso .js contendo o cdigo os mesmos j implementam as validaes em JavaScript (Client)
JavaScript que deve ser usado em diversos pontos do projeto e C# (Server) automaticamente.
e ligando este arquivo s pginas ASPX na TAG <head>, como A Tabela 1 mostra uma descrio de cada validador.
neste outro exemplo: Este evento tipicamente executado quando um boto clica-
do. possvel tambm definir para cada boto um conjunto de
<html xmlns=http://www.w3.org/1999/xhtml> controles a serem validados e assim, validar somente os dados
<head runat=server>
<title>BlogEngine - Criao do Blog</title> necessrios para cada Send.
<script type=text/javascript src=scripts.js></script>
</head>
Entity Framework para acesso aos dados
Outro aspecto importante para o desenvolvimento com ASP.NET
A escolha da melhor opo vai depender de cada caso e de a sua grande conectividade com os bancos de dados. A partir da
cada aplicao, porm, como os arquivos scripts precisam ser verso 3.0 do Framework .NET foi introduzido o Entity Framework
enviados para o cliente junto com o contedo, a tendncia ter (EF) e a linguagem LINQ para manipulao de dados.
a carga cada vez mais lenta, conforme o tamanho deste arquivo Enquanto LINQ permite executar consultas no banco de dados
for crescendo. usando uma sintaxe bem prxima quela do C#, com o EF poss-
Por outro lado, bom observar que alguns browsers desabilitam vel mapear os dados armazenados em bancos de dados relacionais,
por padro a execuo de scripts. Assim, se alguma funo mais como o SQL Server, para classes e objetos.
4. O usurio informa o seu e-mail e senha para fazer o login. Se indicando que trata-se de uma foreign key (chave estrangeira)
o mesmo for bem sucedido, ele redirecionado para a pgina de atravs das letras fk e os nomes da tabela de origem e da
gerenciamento do blog. Caso no tenha xito, uma mensagem de chave estrangeira.
erro ser exibida.
5. Na pgina de abertura deve ser permitido alterar alguns dados Listagem 2. Criao da tabela posts
do blog como nome, descrio, conta de e-mail vinculado e incluir
novos posts. Tambm ser possvel criar um novo blog usando create table posts
(
um link que redireciona o usurio para uma pgina de cadastro id int identity(1,1) not null,
de seus dados. id_blog int not null,
6. Um novo post deve conter o ttulo, o subttulo, as palavras chave post_title varchar(100) not null,
post_subtitle varchar(100) null,
separadas por espao, e o contedo do blog, inicialmente apenas date_created datetime not null default(getdate()),
texto. content varchar(5000),
keywords varchar(1000) null,
primary key (id)
Nesta fase do projeto sero usadas as seguintes tecnologias do )
Framework .NET: go
1. ASP.NET;
alter table posts
2. Acesso aos objetos do banco de dados usando Entity add constraint fk_posts_blogs
Framework; foreign key (id_blog)
references blogs (id)
3. Integrao ASP + JavaScript. go
4. O banco de dados a ser usado ser o SQL Server.
alter table posts
check constraint fk_posts_blogs
Definio do banco de dados go
O banco de dados ter inicialmente duas tabelas, uma para
armazenar os dados dos blogs e os seus gerenciadores e outra
para os posts. Criao do projeto
O banco foi denominado de BlogEngine. A Listagem 1 demons- O projeto foi criado usando o Visual Studio 2010, o Framework 4.0
tra o script para a gerao da tabela blogs que armazena os blogs e o template ASP.NET Empty Web Application. Este template
e os dados dos seus administradores. cria um projeto vazio, sem nenhuma pgina ou cdigo sendo
gerado automaticamente pelo Visual Studio. A Figura 5 mostra
a janela de criao do projeto que acessada pelo menu File >
Listagem 1. Script para a criao da tabela Blogs
New Project.
create table blogs
(
id int identity(1,1) not null,
name varchar(50) not null unique,
password varchar(50) not null,
description varchar(1000) not null,
date_created datetime not null default(getdate()),
admin_name varchar(100) not null,
admin_mail varchar(100) not null,
primary key (id)
)
go
visto que a mesma no integrada diretamente com o servidor. Seguindo na criao do Data Model, o prximo passo escolher as
Como estamos trabalhando em modo local, a autenticao com tabelas. A Figura 11 mostra a janela onde selecionam-se as tabelas
Windows facilita nosso trabalho, j que no necessrio informar do banco de dados. Neste exemplo, vamos mapear todas as tabelas,
usurio e senha. que na prtica iro fazer parte do nosso projeto. Desta forma, o Entity
Ao fazer as configuraes e fechar esta janela o assistente mostra os Framework j cria todas as classes com base nas tabelas mapeadas.
dados da mesma numa janela como a da Figura 10. Neste ponto voc Tambm dado o nome para o Data Model no campo Model
pode tambm dar o nome que achar mais significativo para a conexo namespace.
que foi configurada. Este nome ser usado durante a elaborao do
cdigo em C# para criar o Data Model e acessar os dados. ]
Nota
Para comear a escrever o cdigo correspondente ao evento Click do boto, basta alternar o design
do Visual Studio para mostrar o design da pgina em vez da marcao HTML. Depois disso, basta dar
um clique duplo sobre o boto e o editor do cdigo C# exibido.
Este cdigo usa a string de conexo com o banco que est ar-
mazenada no arquivo Web.config, para poder ler esta usada a
classe ConfigurationManager. Voc vai precisar adicionar nas
clusulas using da pgina a biblioteca System.Configuration para
poder usar esta classe.
O bloco que vai da linha 31 35 contm a instruo LINQ que
compara o e-mail e a senha informados com o banco de dados
retornando uma lista contendo o id do blog. Este id ser arma-
zenado na varivel de sesso para ser usado posteriormente nas
demais pginas para permitir as outras operaes.
muito importante observar que nesta etapa ainda no est sen-
do feita a proteo da senha com criptografia. Assim, este cdigo
ainda no pode ser usado em uma aplicao real. Na prxima
edio vou demonstrar como fazer a proteo da senha usando
criptografia de senha gerando um hash.
Se o usurio informou um endereo de e-mail ou uma senha
incorretos o programa precisa alertar isto. Na verso desta pgina,
optei por emitir um alerta usando a funo alert do JavaScript.
Isto evita que seja necessrio ter um componente oculto para esta
mensagem na pgina e tambm serve para demonstrar como
executar scripts deste tipo a partir do C#. Na linha 36 o bloco
if verifica a validade do login, se estiver incorreto na linha 38
gerado o script para mostrar um alerta para o usurio com a classe
MaxLength 10
ID PassRequiredFieldValidator
ErrorMessage necessrio informar uma senha.<br />
RequiredFieldValidator Display Dynamic
ControlToValidate txtPass
ID txtConfirm
Columns 10
TextBox TextMode Password
MaxLength 10
CompareValidator
ControlToCompare txtPass
ControlToValidate txtConfirm
Display Dynamic
ID btnSend
Text Enviar
<%@Page ErrorMessage=necessrioinformarumnomeparaoautor.<br/>
Language=C# Display=Dynamic
AutoEventWireup=true ControlToValidate=txtAuthor/>
CodeBehind=NewBlog.aspx.cs Endereodee-mail<br/>
Inherits=BlogEngine.NewBlog%> <asp:TextBox
runat=server
<!DOCTYPEhtmlPUBLIC-//W3C//DTDXHTML1.0Transitional//EN ID=txtMail
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd> Columns=100
MaxLength=100/><br/>
<htmlxmlns=http://www.w3.org/1999/xhtml> <asp:RequiredFieldValidator
<headrunat=server> runat=server
<title>BlogEngine-CriaodoBlog</title> ID=EmailRequiredFieldValidator
<scripttype=text/javascriptsrc=scripts.js></script> ErrorMessage=necessrioinformarumendereodee-mail.<br/>
</head> Display=Dynamic
<body> ControlToValidate=txtMail/>
<h1>BlogEngine-Criarnovoblog</h1> <asp:RegularExpressionValidator
<ahref=Default.aspx>Logoff</a>-Criarconta runat=server
<hr/> ID=EmailRegularExpressionValidator
Useestapginaparacriaroseublog.<br/> ErrorMessage=Endereodee-mailinvlido.<br/>
Oendereodee-mailserusadoparaoseulogin.<hr/> ValidationExpression=^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))
Spodehaverume-mailparacadablog.<br/> ([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
<formid=form1runat=server> ControlToValidate=txtMail/>
NomedoBlog<br/> <asp:CustomValidator
<asp:TextBox ID=CustomValidatorEmail
runat=server runat=server
ID=txtName ErrorMessage=Useoutroe-mail.Estejestsendousado.<br/>
Columns=50 Display=Dynamic
MaxLength=50/><br/> ControlToValidate=txtMail
<asp:RequiredFieldValidator SetFocusOnError=True
runat=server onservervalidate=CustomValidatorEmail_ServerValidate/>
ID=NameRequiredFieldValidator Senha<br/>
ErrorMessage=necessrioinformaronome.<br/> <asp:TextBox
Display=Dynamic runat=server
ControlToValidate=txtName/> ID=txtPass
<asp:CustomValidator Columns=10
ID=CustomValidatorName TextMode=Password
runat=server MaxLength=10/><br/>
ErrorMessage=Useoutronome.Estejestsendousado.<br/> <asp:RequiredFieldValidator
Display=Dynamic runat=server
ControlToValidate=txtName ID=PassRequiredFieldValidator
SetFocusOnError=True ErrorMessage=necessrioinformarumasenha.<br/>
onservervalidate=CustomValidatorName_ServerValidate/> Display=Dynamic
Descriodocontedodoblog<br/> ControlToValidate=txtPass/>
<asp:TextBox Confirmaodasenha<br/>
runat=server <asp:TextBox
ID=txtDescription runat=server
Columns=50 ID=txtConfirm
Rows=5 Columns=10
TextMode=MultiLine TextMode=Password
MaxLength=1000/><br/> MaxLength=10/><br/>
<asp:RequiredFieldValidator <asp:CompareValidator
runat=server runat=server
ID=DescriptionRequiredFieldValidator ID=PassCompareValidator
ErrorMessage=necessrioinformarumadescrio.<br/> ControlToCompare=txtPass
Display=Dynamic ControlToValidate=txtConfirm
ControlToValidate=txtDescription/> Display=Dynamic
Nomedoautor<br/> ErrorMessage=Assenhasnoconferem.<br/>/>
<asp:TextBox <asp:Button
runat=server runat=server
ID=txtAuthor ID=btnSend
Columns=100 OnClientClick=confirmacao(Confirmaoenvio?);
MaxLength=100/><br/> Text=Enviaronclick=btnSend_Click/>
<asp:RequiredFieldValidator </form>
runat=server </body>
ID=AutorRequiredFieldValidator </html>
Na interface foram definidos dois controles do tipo CustomValida- Listagem 8. Enviando e validando o nome
tors. Estes controles executam um cdigo no lado do servidor que 42 protected void CustomValidatorName_ServerValidate(object source,
deve retornar se o contedo foi validado ou no. Para escrever um 43 ServerValidateEventArgs args)
event handler em seu cdigo para um controle deste, voc precisa 44 {
45 var dataModel = new BlogEngineEntities(ConfigurationManager
selecionar o controle (em modo design no Visual Studio) e na janela 46 .ConnectionStrings[BlogEngineEntities].ToString());
onde se visualiza os eventos associados com o controle, dar um duplo 47 var list = from blog in dataModel.blogs
clique sobre o item ServerValidate. Esta ao vai exibir o editor de 48 where blog.name.ToUpper() == args.Value.ToUpper()
49 select blog.name;
cdigos onde voc pode entrar com o cdigo C# que deve ser parecido 50 args.IsValid = list == null || list.Count() == 0;
com o da Listagem 8. Estes controles foram utilizados pelo fato de ser 51 }
necessrio criar validaes customizadas, mas, utilizando os recursos
Listagem 9. Validando o e-mail
de validaes do prprio ASP.NET, vistos anteriormente.
O mtodo consulta no banco de dados por outros ttulos de 53 protected void CustomValidatorEmail_ServerValidate(object source,
54 ServerValidateEventArgs args)
blog iguais ao que o usurio digitou. Se nenhum for encontrado a
55 {
pgina vai ser validada. Este cdigo inicia-se na linha 45 criando 56 var dataModel = new BlogEngineEntities(ConfigurationManager
uma instncia do Data Model definido no projeto para poder 57 .ConnectionStrings[BlogEngineEntities].ToString());
58 var list = from blog in dataModel.blogs
conectar-se ao banco. 59 where blog.admin_mail.ToLower() == args.Value.ToLower()
Na linha 47 foi definida a instruo LINQ que faz a comparao 60 select blog.admin_mail;
do ttulo do blog. Para poder tornar a consulta case insensitive o 61 args.IsValid = list == null || list.Count() == 0;
62 }
cdigo converte tanto o contedo do banco como o que foi digitado
pelo usurio para maisculas para fazer a comparao. Listagem 10. Inserindo o registro do blog
Por fim, na linha 50, se nenhum registro foi encontrado, a pgina
16 protected void btnSend_Click(object sender, EventArgs e)
(que est embutida no parmetro args) validada. 17 {
Da mesma forma que necessrio validar o blog para que o ttulo 18 if (Page.IsValid)
19 if (InsertBlog())
seja nico, o endereo de e-mail tambm precisa passar por esta
20 Response.Redirect(Default.aspx);
validao. Na Listagem 9 voc verifica como ficou definido o c- 21 }
digo que consulta o banco de dados para comparar o endereo de 22
23 private bool InsertBlog()
e-mail. Observe que este evento s vai ser disparado se o endereo 24 {
j foi validado pelo RegularExpressionValidator. 25 var model = new BlogEngineEntities(ConfigurationManager
Este mtodo bem parecido com o que valida o ttulo do blog. 26 .ConnectionStrings[BlogEngineEntities].ToString());
27 var blog = new BlogEngine.blogs()
Na linha 56 criada a instncia para o Data Model usando as con- 28 {
figuraes de string de conexo que foram armazenadas. Criando 29 id = 0,
esta instncia se torna possvel o uso do Entity Framework, para 30 admin_mail = txtMail.Text,
31 admin_name = txtAuthor.Text,
a persistncia/consulta dos dados. 32 name = txtName.Text,
Da linha 58 at a 60 definida a instruo LINQ que faz a consul- 33 password = txtPass.Text,
ta no banco de dados. Note que desta vez, para fazer a comparao 34 description = txtDescription.Text,
35 date_created = DateTime.Now
case insensitive, foi usado o mtodo ToLower() para o contedo 36 };
do banco e do controle. Assim, caso o usurio coloque algum 37 model.AddObject(blogs, blog);
38 return model.SaveChanges(System.Data
valor minsculo ou maisculo no teremos problemas, visto que
39 .Objects.SaveOptions.AcceptAllChangesAfterSave) > 0;
sempre convertermos os mesmos para minsculos. 40 }
O mtodo finaliza verificando se algum endereo foi retornado
e faz a validao da pgina.
Uma vez definidos os mtodos deve ser escrito o cdigo que en- O mtodo InsertBlog inicia-se na linha 23. Em resumo ele cria
via os dados para o banco e cria o blog. Esta ao vai ser executada um Data Model, configura um novo objeto para insero no banco
quando o usurio der um clique no boto que foi definido. Assim, e envia os dados para este.
para escrever o cdigo, d um duplo clique neste elemento. Na linha 25 novamente est sendo criado o Data Model partindo
O cdigo para inserir os dados est na Listagem 10. da configurao armazenada no arquivo Web.Config.
Este cdigo est dividido em dois mtodos, o primeiro, corresponde A partir da linha 27 definido um novo objeto usando a classe
ao mtodo criado automaticamente pelo Visual Studio como Event blogs atravs da inicializao direta, ou seja, estou passando os
Handler para o evento click do boto. Este mtodo bem simples. Ele valores das propriedades diretamente no momento da inicializao
verifica se a pgina est vlida, caso positivo, se o mtodo que insere aps chamar o construtor. Este tipo de sintaxe torna o cdigo mais
os dados no banco (chamado aqui de InsertBlog) retornar sucesso fcil de entender, embora, se quiser definir um construtor persona-
a aplicao redireciona para a pgina inicial novamente para que o lizado ou, criar uma instncia para em seguida informar os valores
usurio possa fazer login e iniciar a administrao do blog. para as propriedades dos objetos, no h nenhum problema.
U AMPLIE sua escolha de APIs com C, C++, .NET, ODBC, JDBC, PHP e SQL.
Corpo
ID NameRequiredFieldValidator
ErrorMessage necessrio informar o nome.<br />
Display Dynamic
Como na pgina existem dois botes e
para cada click causada uma validao,
RequiredFieldValidator a utilizao de um ValidationGroup
ValidationGroup BlogData
necessria para que cada click em cada
boto faa a validao em um conjunto
especfico de controles.
ControlToValidate txtName
Novamente ser necessrio usar um
controle Custom Validator para verificar
ID CustomValidatorName
se ao alterar o nome do blog no se est
informando um que j esteja cadastrado.
CustomValidator ErrorMessage Use outro nome. Este j est sendo usado.<br />
Display Dynamic
ControlToValidate txtName
SetFocusOnError True
ValidationGroup BlogData
ID txtDescription
Columns 50
TextBox Rows 5
TextMode MultiLine
MaxLength 1000
ID DescriptionRequiredFieldValidator
ErrorMessage necessrio informar uma descrio.<br />
RequiredFieldValidator Display Dynamic
ValidationGroup BlogData
ControlToValidate txtDescription
ID txtAuthor
TextBox Columns 100
MaxLength 100
ID AutorRequiredFieldValidator
ErrorMessage necessrio informar um nome para o autor.<br />
RequiredFieldValidator Display Dynamic
ValidationGroup BlogData
ControlToValidate txtAuthor
ID txtMail
TextBox Columns 100
MaxLength 100
ID EmailRequiredFieldValidator
ErrorMessage necessrio informar um endereo de e-mail.<br />
RequiredFieldValidator Display Dynamic
ValidationGroup BlogData
ControlToValidate txtMail
ID EmailRegularExpressionValidator
ErrorMessage Endereo de e-mail invlido.<br />
^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]
RegularExpressionValidator ValidationExpression
{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
ValidationGroup BlogData
ControlToValidate txtMail
Para o controle GridView foi definida uma coluna na marcao Listagem 12. Cdigo controlando o carregamento da pgina
HTML como est detalhado a seguir:
11 protected void Page_Load(object sender, EventArgs e)
<asp:GridView 12 {
AutoGenerateColumns=false 13 if (Session[UserId] == null)
Width=100% 14 Response.Redirect(Default.aspx);
runat=server 15
ID=grdPosts> 16 if (!Page.IsPostBack)
<Columns> 17 loadBlogData();
<asp:BoundField DataField=post_title /> 18 }
</Columns>
</asp:GridView> Listagem 13. Carregando os dados
Iniciando com
Threads no C#
T
hreads refere-se tcnica em que a execuo de
um determinado processo (tarefa) dividido em Resumo DevMan
dois ou mais processos, permitindo a execuo
de diversas tarefas de maneira concorrente. De que se trata o artigo:
O conceito de multithreading apresenta um modelo de O artigo trata de como utilizar threads no C#, tornando possvel que sua
programao que permite executar mltiplas tarefas, aplicao execute N tarefas ao mesmo tempo. Desta forma, um processo
compartilhando recursos de um processo e executan- no ir depender de outro para ser executado, por exemplo.
do de forma independente. Logo, o programador deve
evitar que duas ou mais threads operem em um mesmo Em que situao o tema til:
recurso (arquivo, endereo de memria ou conexo A conexo com um banco de dados pode ser um processo demorado e
de rede) Um sistema que utiliza multithreading possui em alguns casos este processo realizado na inicializao de uma aplica-
melhor desempenho em computadores com mltiplos o. Esta demora pode causar ao usurio a impresso de que a aplicao
ncleos de processamento, pois esses ncleos permitem esteja travada. Neste contexto, uma forma de evitar esta situao
que as tarefas de cada thread sejam executadas de forma utilizar uma thread para realizar este processo de conexo, permitindo
simultnea. Este escalonamento de tarefas (multithreads) que a aplicao trabalhe demais processos enquanto a conexo no
permite que threads trabalhem de maneira simultnea e concluda, por exemplo, gerar e exibir formulrios da aplicao. Esse
independente, logo, o programador deve evitar que duas um dos exemplos em que as threads podem ser utilizadas.
ou mais threads operem em um mesmo recurso (arquivo,
endereo de memria ou conexo de rede). Caso acon- Iniciando com Threads no C#:
tea a aplicao apresentar um erro conhecido como O suporte a threads no contexto de aplicaes (softwares) um recurso
deadlock. Theads devem ser programadas para cooperar fornecido pelo prprio Sistema Operacional. Uma thread responsvel
e no competir. O escalonamento (Nota do DevMan 1) por executar tarefas dentro de uma aplicao. O conceito de multithrea-
entre threads segue a mesma lgica do escalonamento ding aplicado quando estas tarefas so divididas em duas ou mais thre-
entre processos. Um mtodo que busca evitar situaes ads, buscando diminuir o tempo de processamento destas tarefas. O .NET
de deadlock conhecido como Thread safety. Este conceito oferece um componente que manipula threads dentro de uma aplicao,
ser abordado no decorrer do artigo. chamado BackgroundWorker. Este artigo introduz o conceito de threads
Para exemplificar threads, ao realizar um Ctrl + Shift + e apresenta uma implementao para conexo com o banco de dados,
Del em seu computador e acessando a opo Iniciar o utilizando uma thread, por meio do componente BackgroundWorker.
Gerenciador de tarefas possvel notar que o sistema
operacional Windows trabalha com vrias tarefas ao
mesmo tempo, como pode ser visto na Figura 1.
Em uma situao onde um determinado processamen- Nota do DevMan 1
to seja realizado por um processador de cinco ncleos,
em teoria, o processador seria capaz de realizar cinco Escalonamento de processos uma atividade organizacional feita pelo escalonador da CPU. O
aplicaes ao mesmo tempo, porm, existem outros di- escalonador escolhe o processo que tem mais prioridade e menos tempo e coloca-o na memria
principal, desta maneira o processador evita ficar ocioso.
versos aplicativos em execuo. Isso possvel porque o
processador consegue trabalhar com todos os aplicativos Para que o multithreading seja manipulado corretamente, as linhas de execuo devem ser
sincronizadas para que os dados sejam processados na ordem correta. Desta maneira trabalhar
e apresentar resultados satisfatrios devidos veloci- com este conceito requer muito cuidado na implementao, pois todas as threads que esto sendo
dade de seu processamento. Sendo assim os aplicativos manipuladas dentro devem funcionar muito bem sincronizadas, principalmente se estiverem
parecem estar em execuo simultaneamente. trabalhando com variveis dependentes. Sendo assim, deve ser respeitada a ordem em que foram
escalonadas, para evitar um possvel deadlock.
Assim como os processos, as threads possuem estados
em seu ciclo de vida, dentro de um sistema as aes e Deadlock caracterizado por um impasse entre dois ou mais processos, sendo assim impedidos de
continuar suas execues, ou seja, bloqueados.
ordens de uma thread so controladas por uma tabela
de threads que armazena informaes de seu fluxo de
execuo, o nome desta tabela Thread TCB (Task Control Block) e O uso de threads traz muitos benefcios, alguns deles podem
a mesma contm: ser destacados:
O endereo da pilha; Velocidade de criao das threads: as threads so mais fceis
O contador de programa; de criar e destruir que os processos, pois elas no tm quaisquer
Registrador de instrues recursos associados a elas. Em alguns sistemas criar um thread
Registradores de dados, endereos, flags; pode ser cem vezes mais rpido do que criar um processo.
Endereos das threads filhas; Capacidade de resposta: a utilizao do multithreading pode
Estado de execuo. permitir que um programa continue executando e respondendo
ao usurio mesmo se parte dele est bloqueada ou executando
A comunicao entre threads pode ser realizada por meio de uma tarefa demorada. Por exemplo, enquanto um navegador Web
variveis globais do processo que as criou. Existem tcnicas que carrega uma figura ele permite a interao com o usurio.
podem ser utilizadas para realizar o sincronismo das mesmas, Compartilhamento de recursos: todos os recursos alocados e
como monitores e semforos, que possuem recursos capazes utilizados pelo processo aos quais pertencem so compartilhados
de indicar a ordem de execuo dos processos e so utilizadas pelas threads.
para evitar condies concorrncia. A Figura 2 apresenta um Economia: como as threads compartilham recursos dos processos
exemplo de processos com apenas uma ou com mltiplas threads aos quais pertencem, mais econmico criar e realizar a troca de
(multithreading). contexto de threads (Nota do DevMan 2).
Nota do DevMan 2
Troca de contexto de threads uma ao onde uma thread pode sair do perodo de processamento
e outra pode assumir seu lugar, sem que sua tarefa esteja concluda. Quando a thread retomar
seu processo, ela ser restaurada do ponto onde parou. Este termo tambm conhecido como
chaveamento ou mudana de contexto.
Threads em C#
Todos os programas desenvolvidos em C# possuem uma
thread, conhecida como thread principal, que responsvel
por controlar a execuo total de um programa. Porm, em
muitos casos esta thread principal acaba sendo sobrecarregada
devido ao acmulo de tarefas que necessitam ser executadas ao
Figura 1. Gerenciador de tarefa do MS Windows.
mesmo tempo. Para estes casos, aplica-se multithreading, onde
os processos so divididos e assim seu tempo de execuo
reduzido. Por exemplo, enquanto a thread principal se encar-
rega de trabalhar interfaces com o usurio, como carregar
formulrios e componentes dos mesmos, uma segunda pode
se responsabilizar por manter a conexo com o banco de dados
(Nota do DevMan 3).
Existem inmeras maneira de implementar threads em softwa-
res. Talvez a mais simples seja criar um mtodo exclusivo para
execuo da tarefa desejada dentro de uma classe, como pode ser
Figura 2. Processos utilizando uma ou mltiplas threads visto na Listagem 1.
01 publicclassExemploThread 01 privatevoidExecutarThread()
02{ 02 {
03publicvoidChamarThread() 03 objectbloqueador=newobject();
04{ 04 boolok;
05System.Threading.ThreadStartts= 05
06newSystem.Threading.ThreadStart(ExecutarThread); 06 lock(bloqueador)
07System.Threading.Threadt= 07 {
08newSystem.Threading.Thread(ts); 08 if(!ok)
09t.IsBackground=true; 09{
10t.Start(); 10MessageBox.Show(Exemplobloqueiodethreads);
11} 11ok=true;
12 12}
13privatevoidExecutarThread() 13 }
14{ 14 }
15//Cdigoaserexecutadopelathread
16}
17}
Enquanto a thread estiver em estado bloqueado (lock), como foi
Listagem 2. Iniciando uma thread. aplicado na linha 6, ela no consome recursos do sistema. O estado
01 ExemploThreadet=newExemploThread(); lock muito utilizado onde existe muita condio de concorrn-
02 et.ChamarThread(); cia para evitar que um programa entre em estado de deadlock.
Outra maneira de realizar essa espera entre threads utili-
zando o mtodo Join(), que tem seu funcionamento parecido ao
A thread t, criada na linha 7, tem a responsabilidade de iniciar a lock(). Porm no mtodo Join() quando a thread atual finalizar
execuo de uma nova thread em segundo plano. Desta maneira, sua execuo, a thread em espera ir retomar automaticamente
assim que a thread em primeiro plano terminar sua execuo, sua execuo. Na Listagem 4 nota-se que a thread principal ir
automaticamente as aes da thread t (que opera em segundo aguardar a execuo total do mtodo atribudo a thread ts, para
plano) so interrompidas. ento prosseguir a execuo do sistema.
O mtodo Start() o responsvel por executar a thread t, e quando
executado uma propriedade da thread chamada IsAlive marca- Listagem 4. Mtodo thread safety Join().
da como true, indicando que a thread est em execuo. Quando
01 publicvoidChamarThread()
esta thread terminar seu trabalho o valor desta propriedade ser 02 {
false. Neste exemplo, a thread t responsvel por executar todo o 03 System.Threading.ThreadStartts=
04 newSystem.Threading.ThreadStart(ExecutarThread);
bloco de instrues presente no mtodo ExecutarThread(), como
05 System.Threading.Threadt=
foi definido na linha 5 e a propriedade IsBackground indica que 06 newSystem.Threading.Thread(ts);
a thread t ser executada em segundo plano. Desta maneira, as 07 t.IsBackground=true;
08 t.Start();
aes da thread t sero escalonadas juntamente com as aes da
09 t.Join();
thread principal e a thread t ser interrompida assim que a thread 10 Console.WriteLine(aThreadtfinalizousuaexecuo!);
principal terminar de executar suas tarefas. 11 }
12
A Listagem 2 apresenta a classe ExemploThread instanciada e 13 privatevoidExecutarThread()
a chamada ao ChamarThread()que inicia a thread. 14 {
15 for(inti=0;i<10;i++)
16 Console.WriteLine(contando:+i+/n);
Thread safety 17 }
Este conceito aplicado para programas multithreading e diz-se
que um cdigo thread-safety quando ele executado simultanea-
mente de maneira correta entre vrias threads. Caso o cdigo no Na Figura 3 pode ser visto o resultado da execuo deste mto-
seja thread-safety, o programa pode apresentar erros inesperados do, utilizando o mtodo Join(), onde exibida a contagem que
apresentada a cada vez que ocorre uma iterao, e apenas ao Na aplicao proposta para este artigo ser utilizado este compo-
realizar o final da contagem o programa finalizado. nente para realizar uma conexo com o banco de dados segura, no
Na Figura 4 o mesmo mtodo da Listagem 4 apresentado, consumindo processamento da thread principal do programa. Esta
porm sem utilizar o mtodo Join(). Note ento que a thread t, tarefa ficar sob total responsabilidade do BackgroundWorker.
responsvel pela contagem, foi bloqueada e finalizada assim Desta maneira, caso o acesso ao banco de dados seja lento, o
que a thread principal terminou sua execuo, sem finalizar a programa no ficar travado. Para este projeto ser utilizada uma
contagem. aplicao Windows Form Application com o Visual Studio 2010.
Na Figura 5 possvel visualizar a tela j finalizada do sistema
onde, aps a conexo com o banco de dados ser bem sucedida, uma
barra de progresso (componente ProgressBar) ser carregada,
alm de alterar o texto de um label de status para conectado
caso a conexo com o banco de dados seja bem sucedida.
Nota do DevMan 4
O componente BackgroundWorker nativo da biblioteca .NET e se encontra no grupo Components
dentro da Toolbox .
Figura 3. Resultado do mtodo ExecutarThread(), utilizando Join()
1 System.Threading.ThreadStartts=
Figura 5. Componentes do projeto
2newSystem.Threading.ThreadStart(ExecutarThread);
3 System.Threading.Threadt= Para realizar a conexo com o banco de dados, sero utili-
4newSystem.Threading.Thread(ts);
5 t.Sleep(3000);
zados os seguintes namespaces: System.Data e System.Data.
SqlClient. Os mesmos possuem classes para a manipulao de
dados, mas especificamente o SqlClient, utilizado para realizar
Os mtodos Lock(), Join() e Sleep() so muito teis para tratar conexo com o banco de dados. Ambas fazem parte do ADO
o conceito de multithreading de maneira segura, ou seja, aplicar o .NET (Nota do DevMan 5).
thread safety.
Nota do DevMan 5
Tutorial
A plataforma .NET dispe de um extenso conjunto de recursos para tarefas relacionadas ao acesso
a dados. Exemplos so as tecnologias ADO.NET (ActiveX Data Object for .NET) e LINQ to SQL. No
caso do ADO.NET, os principais bancos de dados do mercado oferecem suporte para a construo de
Iniciando a aplicao solues .NET baseadas nos mesmos. Embora o ADO.NET conte com uma ampla gama de recursos que
O C# oferece um componente que realiza a manipulao de threads atendem praticamente qualquer tipo de demanda, o mesmo no possui um mecanismo nativo para
de maneira confivel, o BackgroundWorker (Nota do DevMan 4). o tratamento de dados por meio de tcnicas de orientao a objetos.
Nota do DevMan 6
O SqlConnection um componente que representa uma conexo de rede com o banco de dados
SQL Server e o DataSet um componente da arquitetura ADO.NET responsvel por manipular e
representar as tabelas de banco de dados.
1 publicpartialclassForm1:Form
01 publicForm1()
2 {
02 {
3 publicDataSetds;
4 SqlConnectionconn; 03 InitializeComponent();
5 04
6 publicstringConexao=DataSource=.\\SQLEXPRESS; 05 //Ajusta
AttachDbFilename=+Environment.CurrentDirectory+ 06 this.backgroundWorker=newBackgroundWorker();
\\NORTHWND.mdf;IntegratedSecurity=True;ConnectTimeout=30; 07 this.backgroundWorker.DoWork+=
UserInstance=True; 08 newDoWorkEventHandler(backgroundWorker_DoWork);
7 } 09 this.backgroundWorker.ProgressChanged+=
10 newProgressChangedEventHandler(backgroundWorker_ProgressChanged);
11 this.backgroundWorker.RunWorkerCompleted+=
As aes do componente BackgroundWorker so controla- 12 newRunWorkerCompletedEventHandler(
das por meio de trs eventos: DoWork(),ProgressChanged() e 13 backgroundWorker_RunWorkerCompleted);
14 this.backgroundWorker.WorkerReportsProgress=true;
RunWorkerCompleted(). A compreenso destes eventos extre-
15 this.backgroundWorker.RunWorkerAsync();
mamente necessria, pois a partir deles sero aplicadas as regras 16 }
de negcio para a conexo com o banco de dados. Veja como os
mesmos funcionam na Tabela 1.
Uma forma mais detalhada da ordem dos mtodos do Back- Eventos do BackgroundWorker
groundWorker pode ser visualizada em um Diagrama de ativi- Na Listagem 7 o componente BackgroundWorker foi instanciado
dade, que pode ser visto na Figura 6. e na sequncia seus trs eventos de manipulao foram invocados.
Uma dica muito interessante no uso do BackgroundWorker A propriedade WorkerReportProgress foi alterada para true, ou seja,
no manipular objetos de interface de usurio dentro do evento o BackgroundWorker habilitado para reportar atualizaes que
DoWork(). Para realizar estas tarefas recomendvel utilizar o ocorram no seu andamento. Por fim, o mtodo RunWorkerAsync()
evento ProgressChanged(). Existe uma maneira de manipular foi invocado. Este mtodo responsvel pelo incio da execuo
interfaces de usurio no evento DoWork() e ser apresentada do BackgroundWorker, ou seja, inicia em uma nova thread todas
ainda neste artigo. aes que sero geradas.
No mtodo construtor do Form1 sero implementadas a execu- Na Listagem 8 possvel notar que o evento DoWork() respon-
o destes trs eventos do BackgroundWorker. Na Listagem 7 svel por realizar a conexo com o banco de dados NORTHWND.
possvel verificar o mtodo construtor do Form1. DBF que foi adicionado ao /bin/debug do projeto, porm, alm
Figura 7. Erro ao realizar conexo com o banco de dados. importante salientar que no exemplo anterior no foi adiciona-
do nenhum parmetro em nossa query. Caso isso fosse necessrio,
uma boa prtica de programao no concatenar diretamente
Nota do DevMan 9 os valores da query, visto que sua aplicao se tornaria vulne-
rvel a um ataque via SQL Injection (Nota do DevMan 10). Na
Windows Forms uma tecnologia do .NET Framework presente desde as primeiras verses da
Listagem 12 possvel visualizar um exemplo vulnervel. Isso
plataforma, sendo um dos principais meios para o desenvolvimento de aplicaes dotadas de
interfaces grficas. Estas so acionadas atravs da execuo de programas executados a partir do acontece pelo fato do usurio mal intencionado ter a possibilidade
ambiente Windows. O Windows Forms corresponde, basicamente, continuao na plataforma de colocar todos os tipos de caractere por um campo de entrada
.NET do conjunto de padres e recursos que eram empregados na construo de aplicaes visuais
por meio do Visual Basic clssico e de outras ferramentas como Delphi. O desenvolvimento nesta da aplicao.
tecnologia gira em torno da construo de formulrios (janelas), as quais herdam o tipo bsico
Form (namespace System.Windows.Forms). Dentro do Visual Studio existe um excelente suporte Listagem 11. Select na tabela Categories do banco de dados NORTHWND.
para a elaborao de aplicaes baseadas em Windows Forms. Esta IDE oferece uma ampla gama de
controles visuais como botes, caixas de texto/seleo, grids etc.Tais componentes sendo combinados
SqlDataAdapterda=newSqlDataAdapter(SELECT*FROMCategories,conn);
e inseridos em formulrios, de forma a criar aplicaes com interfaces leves, com um aspecto visual
satisfatrio e que atendam aos mais variados tipos de demanda.
ds=newDataSet();
//PreencheoDataSetcomoSqlDataAdapter
Buscando dados do banco de dados da.Fill(ds);
Caso fosse necessrio a utilizao de parmetros no exemplo a compreenso de forma clara sobre a seqencia de processamen-
da Listagem 12, voc poderia utilizar a classe SqlCommand to e o que est sendo realizado pela thread e tambm possvel
em conjunto com o SqlDataAdapter, conforme o exemplo da aplicar um controle de erros ou um controle de transio atravs
Listagem 13. destes eventos, evitando assim deadlocks.
Na aplicao modelo pode ser visto como o BackgroundWorker
realizou o tratamento de uma conexo com o banco de dados,
Nota do DevMan 10 aplicando um controle de exception nesta conexo, aumentando
assim seu desempenho e sua usabilidade do programa. Outro
SQL Injection (termo tambm conhecido em portugus como Injeo de SQL) uma forma de ponto forte foi combinar o componente ProgressBar com o Back-
ataque que busca explorar vulnerabilidades em aplicaes que utilizem bancos de dados relacionais. groundWorker, visto que o ProgressBar um componente muito
Assim, um usurio interessado em promover aes deste gnero, procura inserir caracteres especiais
e comandos SQL em parmetros que so enviados a uma base (a partir de formulrios de cadastro ou til dentro de um sistema para manter o usurio informado que o
filtros em telas de pesquisa), de maneira que o processamento de tais instrues leve a alteraes e mesmo no est travado e quanto ser a espera de tarefas. Os even-
outros danos indesejveis a um banco de dados. tos do BackgroundWorker facilitam a aplicao da ProgressBar.
T Resumo DevMan
rabalhar com arquivos, diretrios e operaes
de IO uma tarefa considerada trivial para
desenvolvedores. Certamente a grande maioria De que se trata o artigo:
das aplicaes ainda necessita realizar o tratamento de O artigo apresenta as classes que o .NET framework dispe para realizar-
arquivos, diretrios, leitura de imagens, vdeos e outros mos o tratamento de arquivos, diretrios do sistema e drives instalados
dados que esto armazenados tanto no disco rgido no sistema operacional, utilizando prticas que podem melhorar o de-
como em bancos de dados relacionais. A m utilizao sempenho e manter a segurana nas atividades relacionadas a operaes
de comandos para estas operaes podem comprometer IO (entradas e sadas) em aplicaes .NET.
a estrutura de uma aplicao inteira. Desta forma, para
facilitar as operaes I/O em aplicaes .NET, o .NET Em que situao o tema til:
framework dispe de um namespace especfico para Na grande maioria dos sistemas desenvolvidos, existe a necessidade
estas tarefas. Trata-se do namespace System.IO. Com as de trabalharmos com arquivos organizados em diretrios no disco
classes disponibilizadas neste namespace, o desenvol- rgido da mquina ou leitura de drives e localizao, manipulao e
vedor pode manipular diretrios, arquivos e drivers armazenamento de informaes. Quando necessitamos manter alguma
do sistema operacional, alm de manipular leitura e informao que no seja em bancos de dados relacionais, precisamos
reproduo de udio, vdeo, imagens etc. manter estas informaes organizadas de uma forma que permita a
Este conjunto de classes so derivadas do tipo FileSys- leitura pela aplicao.
temClass, que nada mais que um conjunto de classes
especializadas em manipulao de informao para Primeiros passos com o namespace System.IO:
arquivos, drivers e diretrios. Alm deste conjunto de Neste artigo veremos quais as classes disponveis no .NET framework
classes, este namespace disponibiliza uma srie de ou- que possibilitam a manipulao/edio e excluso de arquivos fsicos e
tras classes, que tratam das mais variadas operaes de diretrios de sistema em conjunto com as funcionalidades disponveis
I/O possveis, como escrita e leitura em arquivos. pelo sistema operacional. Vamos entender a leitura das informaes
importantes de arquivos, diretrios e drives como, por exemplo, localiza-
A Classe FileSystemInfo o, verificao de propriedades, tamanho, espao disponvel no sistema
No namespace System.IO temos uma srie de classes operacional e monitoramento de alteraes.
distintas, sendo cada uma aplicada a um tipo de objeto
diferente no sistema operacional.
A classe FileSystemInfo, a princpio, serve apenas como
classe base, conforme os princpios da Orientao a Ob- A Classe FileInfo
jetos, onde temos uma classe mais generalizada para dar A classe destinada a fornecer informaes de armazenamento
origem classes mais especficas. Ela foi implementada de arquivos no sistema operacional a classe FileInfo. Com ela
justamente para que suas classes filhas (especializadas conseguimos obter, a partir do endereo de um arquivo, a data
como FileInfo) possuam um conjunto de propriedades de criao do arquivo, nome, extenso, atributos etc. Ela possui
e mtodos em comum, no sendo necessrio reescrever todos os mtodos e propriedades da classe FileSystemInfo (j que
os mesmos mtodos em cada classe filha. FileInfo herda de FileSystemInfo), porm, ela tambm possui as
Para conhecermos melhor as propriedades e mtodos suas propriedades e mtodos especficos, caso contrrio, no se
da classe FileSystemInfo, vamos analisar a Tabela 1, onde justificaria a sua criao. Para conhecermos melhor estes mtodos
so listadas as propriedades e a Tabela 2, onde so apre- e propriedades, podemos analisar a Tabela 3 e Tabela 4, onde so
sentados os seus mtodos. mostrados os atributos e mtodos respectivamente.
Propriedade Descrio
permite manipular informaes dos atributos do arquivo ou diretrio que est sendo analisado. Atributos so um conjunto de informaes
utilizadas tanto pelo sistema operacional, aplicaes ou at mesmo pelo usurio, para definir comportamentos de arquivo ou diretrio. Um
Attributes
exemplo de atributo de um arquivo o famoso Somente Leitura. Para verificar todos os atributos possveis de um arquivo ou diretrio,
podemos analisar o enumerador contido no mesmo namespace da classe FileSystemInfo, denominado FileAttributes.
CreationTime permite informar ou ler informao da data em que o arquivo ou diretrio foi criado.
tem como nico objetivo retornar se o arquivo ou diretrio analisado atravs do endereo informado existe ou no no sistema operacional.
Exists
Neste caso a propriedade somente retorna valor e no permite ser alimentada (modificada).
Extension retorna a extenso de um arquivo, por exemplo, em arquivo com o nome File.txt retornar a extenso txt.
retorna o caminho completo do arquivo ou diretrio no sistema operacional, desde o drive inicial at o nome do arquivo ou diretrio no
FullName
sistema.
LastAccessTime informa a data e hora do ltimo acesso de um arquivo ou diretrio.
LastWriteTime informa a data e hora da ltima manipulao de escrita realizada em um arquivo ou diretrio no sistema operacional.
Name diferente da FullName, esta propriedade retorna apenas o nome do arquivo ou diretrio, sem o caminho ou extenso do mesmo.
Mtodo Descrio
AppendText retorna uma instncia da classe StreamWriter, que a classe responsvel por permitir que sejam escritas ou adicionadas informaes no arquivo.
CopyTo fornece a funcionalidade de copiar o arquivo analisado para uma nova localizao no sistema operacional.
cria um arquivo baseado nas informaes definidas para a classe FileInfo ao qual este executado. utilizado quando estamos criando
Create
novos arquivos.
CreateText alm de criar um arquivo, permite escrever um texto no mesmo. Esta funcionalidade ser vista em maior detalhe mais adiante.
Decrypt utilizado para descriptografar um arquivo criptografado.
Encrypt realiza a criptografia de um arquivo.
MoveTo permite que o arquivo que est sendo analisado, seja movido (no cria cpia) para outra localizao no sistema operacional.
Open acessa o arquivo analisado com privilgios especficos, como leitura, escrita etc.
OpenRead permite acessar o arquivo analisado somente como leitura.
OpenText acessa o arquivo analisado e retorna uma instncia da classe StreamReader a qual permite realizar a leitura do contedo de um arquivo.
OpenWrite acessa o arquivo com permisso somente de escrita, ou seja, somente permitido incluir informaes no arquivo.
Replace utilizado para substituir informaes do arquivo.
Neste momento j conhecemos as funcionalidades e possibilida- Caso o desenvolvedor tente instanciar a mesma, receber um erro
des que a classe FileInfo nos permite na manipulao de informa- j em modo de design no cdigo.
es dos arquivos. Referente classe FileSystemInfo, ela no per- Para ilustrar a utilizao da classe FileInfo, podemos verificar
mite ser instanciada, ou seja, no possvel criar um objeto deste o cdigo da Listagem 1, onde estamos retornando informaes
tipo, pois como sua principal funo ser a base de outras classes, de um arquivo denominado Teste.txt localizado no drive C:\ do
esta foi criada como uma classe abstrata (Nota do DevMan 1). sistema operacional. Para fins de exemplo, o arquivo em questo
Propriedade Descrio
retorna uma instncia da classe DirectoryInfo que refere-se ao diretrio pai do diretrio analisado, ou seja, o diretrio um nvel acima. Caso
Parent
acima do diretrio atual esteja apenas o drive ou tambm conhecido como raiz, esta propriedade retorna em branco.
Root retorna a raiz do diretrio, independente do nvel em que o mesmo se encontra.
Tabela 5. Propriedades da classe DirectoryInfo
Mtodo Descrio
Create responsvel por criar um novo diretrio baseado no objeto DirectoryInfo atual.
CreateSubdirectory Como o nome deste mtodo sugere, ele realiza a criao de um subdiretrio, ou seja, um diretrio filho do diretrio atualmente analisado.
utilizado para retornar um conjunto de diretrios filhos do diretrio analisado. Retorna os diretrios em formato de array de objetos do tipo
GetDirectories
DirectoryInfo.
similar ao mtodo GetDirectories, porm ao contrrio de retornar um array com os diretrios, retorna um array dos arquivos contidos no
GetFiles
diretrio analisado. Retorna um array de objetos do tipo FileInfo.
retorna um array de objetos do tipo FileSystemInfo contidos no diretrio analisado, ou seja, retorna arquivos e diretrios, todos em um mesmo
GetFileSystemInfos
array utilizando a classe base de ambos objetos.
MoveTo da mesma forma que trabalha com arquivos, este mtodo realiza a alterao da localizao do diretrio corrente para outro local no sistema operacional.
Os mtodos e propriedades da classe DirectoryInfo so bem similarmente como fizemos com a classe FileInfo. Conforme
intuitivos, porm para vermos como a classe trabalha na prtica, possvel realizar com arquivos, tambm podemos adicionar a
vamos analisar o exemplo da Listagem 2, onde estamos realizando verificao se os diretrios existem, para que no tenhamos uma
a leitura de todos os arquivos contidos no diretrio C:\Windows e exceo em nosso cdigo, conforme a linha 10. Para que possamos
apresentando os mesmos em uma listagem no console. realizar a leitura dos arquivos que o diretrio analisado possui,
Como pode ser verificado na Listagem 2, inicialmente estamos precisamos utilizar o mtodo GetFiles() do objeto do diretrio. Na
criando uma instncia da classe DirectoryInfo e j no momento de linha 12 estamos percorrendo todos os objetos do tipo FileInfo,
instanciar a mesma estamos informando o path deste diretrio, retornados pelo mtodo GetFiles() e em seguida, estamos exibindo
o nome de cada arquivo do diretrio criando uma listagem com
os mesmos.
Listagem 2. Lista de Arquivos em C:\Windows
01 using System;
A Classe DriveInfo
02 using System.IO; Como comentamos no incio deste artigo, alm de permitir a
03 namespace Exemplo manipulao de arquivos e diretrios, o namespace System.IO
04 {
05 class Program
tambm possui a classe DriveInfo (um tanto lgico), especializada
06 { para a manipulao de drives do sistema operacional. Para enten-
07 static void Main(string[] args) dermos melhor o funcionamento da classe, veja suas propriedades
08 {
09 DirectoryInfo diretorio = new DirectoryInfo(@C:\Windows); e mtodos conforme a Tabela 7 e Tabela 8, respectivamente.
10 if (diretorio.Exists) A utilizao da classe DriveInfo no difere em praticamente nada
11 { com a classe DirectoryInfo ou a classe FileInfo. Basta instanciar
12 foreach (FileInfo file in diretorio.GetFiles())
13 { um objeto com a classe e realizar a manipulao das proprieda-
14 Console.WriteLine(Arquivo: {0}, file.Name); des e mtodos disponveis para a mesma. Para exemplificar, na
15 }
Listagem 3, vamos implementar a leitura de todos os drives ins-
16 Console.Read();
17 } talados no sistema e apresent-los em forma de lista, similarmente
18 } como fizemos com os arquivos do diretrio na Listagem 2. Alm
19 }
do nome do driver, vamos apresentar na listagem o tipo de cada
20 }
drive atravs da propriedade DriveType do mesmo.
Propriedade Descrio
retorna o espao livre do drive que est sendo analisado. Esta propriedade pode retornar um valor diferente da propriedade TotalFreeSpa-
AvaliableFreeSpace
ce, pois considera as cotas do drive por usurio.
DriveFormat retorna o tipo de formatao do drive, como NTFS ou FAT32.
retorna o tipo do drive que esta sendo analisado. Para o tipo do drive, o .NET framework possui o enumerador DriveType, o qual est loca-
lizado no mesmo namespace da classe DriveInfo (System.IO). Este enumerador pode ter os seguintes valores:
CDRom um drive ptico como leitor de CD, DVD, Blu-Ray etc.
Fixed um disco rgido local.
DriveType Network um drive mapeado na rede.
NoRootDirectory um drive que no possui um diretrio raiz.
Ram um drive do tipo RAM.
Removable um drive removvel, por exemplo, um pendrive.
Unknown um drive desconhecido. Se encaixa nesta categoria qualquer drive que no se encaixe nas demais acima citadas.
IsReady indica se o drive est pronto para ser acessado.
Name retorna o nome do drive.
RootDirectory retorna um objeto do tipo DirectoryInfo contendo as informaes do diretrio raiz do drive analisado.
TotalFreeSpace retorna o espao livre total do drive (sem considerar cotas de usurios).
TotalSize retorna o tamanho total do drive analisado.
VolumeLabel retorna ou define o rtulo para o drive analisado (somente pode setar esta informao para drives que no so somente leitura).
Mtodo Descrio
um mtodo esttico (Nota DevMan 3), ou seja, no necessita de uma instncia da classe para ser chamado e, tem o objetivo de retornar um array
GetDrives
de objetos do tipo DriveInfo contendo todos os drives instalados no sistema no momento da execuo.
Nota do DevMan 3 05
06
class Program
{
07 static void Main(string[] args)
08 {
Mtodos Estticos (static): so mtodos declarados com o modificador static, o qual tem por objetivo
09 foreach (DriveInfo drive in DriveInfo.GetDrives())
definir que estes mtodos podem ser invocados por outro objeto, sem a necessidade de que a classe
10 {
ao qual estes pertencem seja instanciada primeiramente. Quando um mtodo no esttico, a sua
11 Console.WriteLine(Drive: {0} - Tipo: {1}, drive.Name, drive.DriveType.
execuo est restrita necessidade da classe onde este est definido, devendo estar instanciada em
ToString());
um objeto, caso contrrio no podem ser invocados.
12 }
13 Console.Read();
14 }
A Classe FileSystemWatcher 15 }
16 }
Para finalizar a seo de classes de informao, temos a classe
FileSystemWatcher. Esta classe utilizada para monitorao de
diretrios. Quando desejamos monitorar as alteraes realizadas
em um determinado diretrio do sistema, podemos implementar Vamos verificar as principais propriedades e mtodos da classe
um objeto do tipo FileSystemWatcher. Com este objeto podemos FileSystemWatcher que esto listadas na Tabela 9 e 10 respectiva-
definir o diretrio a ser monitorado, os tipos de alteraes a serem mente. Nesta classe, alm das propriedades e mtodos, temos os
verificadas e qual ao dever ser tomada quando a alterao mo- eventos, conforme a Tabela 11.
nitorada for realizada no diretrio. Um bom exemplo de utilizao Para exemplificar a utilizao da classe FileSystemWatcher, na
da classe FileSystemWatcher a criao de uma lista de log's de Listagem 4 podemos ver a implementao de um monitora-
alterao de um determinado diretrio no sistema. mento no diretrio "C:\" do sistema operacional, onde estamos
Propriedade Descrio
contm a definio se o objeto deve disparar ou no os eventos, ou seja, a definio se estamos monitorando ou no o diretrio especifi-
EnableRaisingEvents
cado. Com isso podemos iniciar e parar o monitoramento conforme desejarmos.
em muitos casos no estamos interessados em monitorar alteraes de todos os arquivos contidos no diretrio analisado, e sim, apenas as alteraes
realizadas em alguns arquivos. Para auxiliar nesta definio, esta propriedade define um filtro para o monitoramento, onde podemos determinar
quais tipos de arquivos que desejamos monitorar. Esta propriedade recebe uma string, conforme a definio de filtro que voc deseja aplicar.
Filter
Por exemplo, se quiser filtrar um arquivo especfico, basta colocar o nome dele nesta propriedade; se deseja monitorar tipos de arquivos, como
arquivos com extenso txt pode alimentar a propriedade com o texto *.txt, porm, o uso de mltiplos filtros, como na string *.txt|*.doc no
suportada. Quando esta propriedade no for informada, realizar a monitorao de todos os arquivos por padro.
IncludeSubdirectories define se o monitoramento dever ser realizado tambm nos subdiretrios do diretrio informado.
define o tipo de alteraes a serem verificadas no monitoramento. Por padro, todas as alteraes de excluso, renomeao e modificao
de arquivos esto habilitadas. Para alimentarmos esta propriedade, o .NET framework dispe do enumerador NotifyFilter que possui as
seguintes opes:
FileName notifica alteraes no nome dos arquivos.
DirectoryName notifica alteraes no nome do diretrio.
NotifyFilter Attributes notifica alteraes em atributos dos arquivos.
Size notifica alteraes no tamanho dos arquivos.
LastWrite notifica alterao na data de ltima alterao do contedo dos arquivos.
LastAccess notifica alterao na data de ltimo acesso dos arquivos.
CreationTime notifica alterao na data de criao dos arquivos.
Security notifica alteraes nas definies de segurana dos arquivos.
Path define o endereo do diretrio a ser monitorado.
Eventos Descrio
Changed disparado quando ocorre alguma alterao em arquivo ou diretrio contido no diretrio monitorado.
Created disparado quando algum objeto (arquivo ou diretrio) criado no diretrio monitorado.
Deleted disparado quando algum objeto excludo do diretrio monitorado.
Renamed disparado quando algum objeto possui seu nome alterado no diretrio monitorado.
Error ocorre quando h um erro interno no monitoramento do diretrio.
verificando todas as alteraes (sem filtros) e estamos dispa- Na Listagem 4 iniciamos criando uma instncia da classe
rando um evento quando um arquivo ou diretrio criado ou FileSystemWatcher. Ento definimos qual o endereo do diretrio
ento quando alterado no diretrio monitorado. que desejamos monitorar, que em nosso caso o diretrio "C:\",
O acoplamento um conceito computacional que indica o grau na propriedade Path do objeto. Nas linhas 11 e 12 estamos adi-
de relacionamento entre diferentes partes de uma aplicao. cionando um manipulador de eventos, conhecido como delegate
Um alto acoplamento implica em um nvel de alta dependncia (Nota do DevMan 4) e, neste caso, do tipo EventHandler, para os
eventos de criao de arquivos e diretrios (Created) e de alterao
de arquivos e diretrios (Changed).
Listagem 4. Monitorando Diretrio
A Classe Path
Listagem 5. Alterando extenso de Path
o estudo de todas as classes vistas anteriormente, podemos
N
verificar a existncia de uma propriedade que sempre funda- 01 using System;
mental ao funcionamento destas. Trata-se da propriedade Path. 02 using System.IO;
03 namespace Exemplo
Esta propriedade a que define o endereo do que estamos mani-
04 {
pulando, visualizando ou criando. Tendo esta importncia, o .NET 05 class Program
framework no poderia deixar de possuir uma classe especfica 06 {
para a manipulao desta propriedade. Um Path nada mais que 07 static void Main(string[] args)
08 {
um endereo de algo no sistema operacional, podendo ser um 09 string path1 = @C:\Teste.txt;
arquivo, diretrio ou drive. Se verificarmos o estudo das demais 10 Console.WriteLine(Path analisado: {0}, path1);
classes acima, veremos que ele sempre foi alimentado com uma 11 Console.WriteLine(Extenso original: {0}, Path.GetExtension(path1));
12 Console.WriteLine(Novo path, com extenso .ini: {0}, Path.
cadeia de caracteres como C:\, a qual indicou o local para onde
ChangeExtension(path1, ini));
desejamos apontar no sistema operacional. 13 Console.Read();
Para a manipulao de paths, o .NET framework dispe da 14 }
classe Path, que fornece mtodos para manipulaes em arquivos 15 }
16 }
do sistema utilizando apenas o endereo (path) do mesmo. Para
Mtodo Descrio
permite gerarmos um novo endereo de path a partir de um existente, alterando apenas a extenso do arquivo contido no path original.
ChangeExtension Este mtodo no altera a extenso do arquivo, e sim, somente a extenso do path retornado. Pode ser utilizado quando desejamos obter
o path para uma cpia de um determinado arquivo, alterando a extenso deste.
Combine permite combinar vrias strings para resultar em uma string contendo um path combinado de todas estas.
retorna o path do diretrio pai contido no path analisado. O path retornado sempre apontar para o diretrio acima do arquivo ou
GetDirectoryName
diretrio analisado no path informado.
retorna a extenso do arquivo apontado pelo path informado. Quando o path informado se refere a um diretrio ou um arquivo que est
GetExtension
sem extenso, retornada uma string em branco.
retorna o nome do arquivo especificado pelo path informado. O nome do arquivo que retornado inclui a extenso do mesmo. Quando o
GetFileName
path analisado apontar para um diretrio, retornado uma string em branco.
GetFileNameWhithout tem o mesmo objetivo do mtodo anterior, porm, o nome do arquivo retornado no possui a extenso adicionada, ou seja, retirada a
Extension informao da extenso do arquivo no nome retornado.
retorna o path completo do local onde a aplicao est sendo executada, adicionando um nome de arquivo, por exemplo. Exemplo: su-
pondo que desejamos criar um novo arquivo chamado teste.txt e que este deva estar no mesmo diretrio da aplicao que est criando
GetFullPath
o arquivo, no precisamos verificar o diretrio da aplicao para montar o path do arquivo, e sim chamar este mtodo passando o nome
do arquivo criado que o mesmo retornar o path completo do arquivo localizado no mesmo diretrio da aplicao executada.
GetPathRoot retorna o diretrio raiz do path informado.
GetRandomFileName gera um nome de arquivo randomizado, ou seja, cria um nome aleatrio para o novo arquivo, por exemplo.
retorna o path para a criao de um novo arquivo temporrio aleatoriamente utilizando o diretrio de arquivos temporrios definido para
GetTempFileName
o sistema/usurio.
GetTempPath retorna o path definido no sistema/usurio como diretrio de arquivos temporrios.
HasExtension retorna a informao se o path analisado possui uma extenso.
IsPathRooted retorna a informao se o path analisado possui um diretrio raiz.