entrada e saída de arquivos em c# - parte2

14
Manipulação de arquivos e pastas A manipulação de arquivos e pastas ocorre quando manipulamos pastas e apenas o arquivo e não o seu conteúdo. Em geral a manipulação de arquivos inclui cópia, movimentação e exclusão de arquivos. O Framework Dot.Net fornece as classes FileInfo e DirectoryInfo para manipulações de arquivos e pastas. Essas classes pertencem ao namespace System.IO. Para cada operação de manipulação criaremos pequenos fragmentos de código que realizam somente a operação em estudo, assim podemos manter o foco na operação e não nos preocuparmos tanto com o aplicativo em si. Você pode depois combinar as idéias utilizadas em cada aplicativo para criar um aplicativo único, robusto, e completo que permita fazer as várias operações com uma única interface. Manipulação de pastas Já vimos no artigo anterior que podemos utilizar a classe estática Directory ou a classe instanciável DirectoryInfo. Utilizaremos aqui a classe DirectoryInfo para realizar as operações com pasta e praticar a criação de objetos com essa classe. Como vimos no artigo anterior, a criação de uma referência a uma pasta se dá da seguinte forma: DirectoryInfo minhaPasta = new DirectoryInfo(@“c:\exemplo”); Agora há duas situações possíveis. A pasta referenciada pode existir ou não. As figuras 1 e 2 mostram o que acontece em termos de referência para a pasta. Memória Auxiliar

Transcript of entrada e saída de arquivos em c# - parte2

Page 1: entrada e saída de arquivos em c# - parte2

Manipulação de arquivos e pastas

A manipulação de arquivos e pastas ocorre quando manipulamos pastas e apenas o arquivo e não o seu conteúdo. Em geral a manipulação de arquivos inclui cópia, movimentação e exclusão de arquivos. O Framework Dot.Net fornece as classes FileInfo e DirectoryInfo para manipulações de arquivos e pastas. Essas classes pertencem ao namespace System.IO.

Para cada operação de manipulação criaremos pequenos fragmentos de código que realizam somente a operação em estudo, assim podemos manter o foco na operação e não nos preocuparmos tanto com o aplicativo em si. Você pode depois combinar as idéias utilizadas em cada aplicativo para criar um aplicativo único, robusto, e completo que permita fazer as várias operações com uma única interface.

Manipulação de pastas

Já vimos no artigo anterior que podemos utilizar a classe estática Directory ou a classe instanciável DirectoryInfo. Utilizaremos aqui a classe DirectoryInfo para realizar as operações com pasta e praticar a criação de objetos com essa classe.

Como vimos no artigo anterior, a criação de uma referência a uma pasta se dá da seguinte forma:

DirectoryInfo minhaPasta = new DirectoryInfo(@“c:\exemplo”);

Agora há duas situações possíveis. A pasta referenciada pode existir ou não. As figuras 1 e 2 mostram o que acontece em termos de referência para a pasta.

Figura 1. Referência a uma pasta existente

minhaPasta

c:\exemplo

Memória Auxiliar (Secundária)

Page 2: entrada e saída de arquivos em c# - parte2

Figura 2. A pasta referenciada não existe

Para sabermos se a pasta de fato existe podemos utilizar a propriedade Exists. Essa propriedade retorna true caso a pasta exista, e retorna false caso ela não exista.

if (minhaPasta.Exists){

MessageBox.Show(“A pasta existe”);}else{

MessageBox.Show(“A pasta não existe”);}

Criação de uma nova pasta

Para o caso em que a pasta não existe, pode ser que queiramos criar essa pasta. Para isso utilizamos o método Create() da classe DirectoryInfo. Observe o exemplo a seguir:

using System;using System.Text;using System.Windows.Forms;using System.IO;

namespace ExemploArquivosSimples{ public partial class Form1 : Form { DirectoryInfo minhaPasta = null; FileInfo meuArquivo = null; public Form1() { InitializeComponent(); }

private void button1_Click(object sender, EventArgs e)

minhaPasta

?

Memória Auxiliar (Secundária)

Page 3: entrada e saída de arquivos em c# - parte2

{ minhaPasta = new DirectoryInfo(@textBox1.Text);

if (minhaPasta.Exists) { MessageBox.Show("A pasta existe"); } else { if (MessageBox.Show("A pasta não existe, deseja criá-la?", "Aviso", MessageBoxButtons.YesNo) == DialogResult.Yes) { //cria a pasta minhaPasta.Create(); } } } }}

Ao ser criada a pasta, passa a haver o vínculo de referência entre a variável do tipo DirectoryInfo e a pasta física criada, conforme mostra a figura 1.

Movimentação de uma pasta

Ao mover uma pasta, você deve ser preocupar com duas questões, não contando o fato de pasta existir ou não. Primeiro qual o caminho da pasta atual a ser movida. Segundo qual o novo caminho de destino da pasta a ser movida (incluindo seu nome original ou um novo nome).

De posse desses dados podemos proceder ao movimento utilizando o método MoveTo. Veja como funciona.

minhaPasta = new DirectoryInfo(@textBox2.Text); string strCaminhoDestino = textBox3.Text;

if (minhaPasta.Exists) { try { minhaPasta.MoveTo(@strCaminhoDestino);

MessageBox.Show("Pasta movida com sucesso"); } catch (Exception objExcecao) { MessageBox.Show(objExcecao.Message); } } else

Criação de uma nova pasta

Movimentação da pasta

Page 4: entrada e saída de arquivos em c# - parte2

{ MessageBox.Show("A pasta existe"); }

É importante utilizar os blocos try...catch em operações com arquivos ou pastas para prever erros que possam ocorrer.

Exclusão de uma pasta

A exclusão de uma pasta é feita utilizando-se o método Delete. Essa função possui duas assinaturas (ou seja duas formas de ser chamada): a primeira sem parâmetros para excluir pastas vazias, e a segunda com um parâmetro boleano (true ou false) para pastas com conteúdo interno (subpastas ou arquivos). O parâmetro boleano serve para dizer se o conteúdo interno da pasta será excluído (true) ou não (false).

A segunda versão do método, quando utilizada com o parâmetro false, produz o mesmo efeito da primeira versão do método, ou seja Delete().

Na maioria das vezes vamos utilizar essa função na sua segunda versão, com o parâmetro igual a true, ou seja excluiremos a pasta e seu conteúdo interno também.

Vejamos um exemplo:

minhaPasta = new DirectoryInfo(@"c:\xpto");minhaPasta.Delete(true);

Aqui dois cuidados são importantes. Não só se deve considerar se a pasta existe ou não, mas também, caso ela exista deve-se ter certeza que ela será apagada.

Podemos adicionar essas medidas de segurança:

minhaPasta = new DirectoryInfo(@"c:\xpto");if (minhaPasta.Exists){ if (MessageBox.Show("Tem certeza?", "Confirmação", MessageBoxButtons.YesNo)== DialogResult.Yes) { try { minhaPasta.Delete(true); } catch (Exception objExcessao) { MessageBox.Show(objExcessao.Message, "Erro"); } }

Exclusão da pasta

Page 5: entrada e saída de arquivos em c# - parte2

}else{ MessageBox.Show("A pasta não existe","Erro");}

Manipulação de arquivos

Agora que sabemos como trabalhar com pastas, vamos aprender a realizar as mesmas operações com arquivos.

Como vimos no artigo anterior, a criação de uma referência a um arquivo se dá da seguinte forma:

FileInfo meuArquivo = new FileInfo(@“c:\exemplo.txt”);

Assim como com as pastas, há duas situações possíveis. Um arquivo referenciado pode existir ou não. As figuras 3 e 4 mostram o que acontece em termos de referência para o arquivo.

Figura 3. Referência a um arquivo existente

Figura 4. O arquivo referenciado não existe

Para sabermos se o arquivo de fato existe podemos utilizar a propriedade Exists. Essa propriedade retorna true caso o arquivo exista, e retorna false caso ele não exista.

meuArquivo

c:\exemplo.txt

meuArquivo

?

Memória Auxiliar (Secundária)

Memória Auxiliar (Secundária)

Page 6: entrada e saída de arquivos em c# - parte2

if (meuArquivo.Exists){

MessageBox.Show(“O arquivo existe”);}else{

MessageBox.Show(“O arquivo não existe”);}

Criação de arquivo

O arquivo pode ser criado, caso ele não exista, utilizando-se o método Create(). Veja um exemplo:

meuArquivo = new FileInfo(@"c:\exemplo.txt");

if (!meuArquivo.Exists){ meuArquivo.Create();}

Cópia de um arquivo

Como vimos no artigo anterior, através do método CopyTo podemos copiar um arquivo. Para isso devemos fornecer ao método o parâmetro do tipo string que indique o caminho da pasta destino da cópia e o novo nome do arquivo. Lembre-se que é sempre importante se certificar que o arquivo existe.

Exemplo:

meuArquivo = new FileInfo(@"c:\exemplo.txt");

if (meuArquivo.Exists){ try { meuArquivo.CopyTo(@"d:\exemp.txt"); } catch (Exception objExcessao) { MessageBox.Show(objExcessao.Message, "Erro"); }}else{ MessageBox.Show("Arquivo inexistente", "Erro");}

Criação de um novo arquivo

Cópia de um arquivo

Page 7: entrada e saída de arquivos em c# - parte2

Observe que além de criar uma cópia do arquivo e colocá-la no local indicado, a cópia também teve seu nome modificado do original.

Movimento de um arquivo

Semelhante ao processo de movimentação de uma pasta, utilizamos o método MoveTo. Esse método também recebe como parâmetro uma string para indicar o destino do arquivo. Veja um exemplo:

meuArquivo = new FileInfo(@"d:\exemplo.txt");

if (meuArquivo.Exists){ try { meuArquivo.MoveTo(@"d:\projetos\exemp.txt"); } catch (Exception objExcessao) { MessageBox.Show(objExcessao.Message, "Erro"); }}else{ MessageBox.Show("Arquivo inexistente", "Erro");}

Observe que também neste caso o arquivo foi renomeado ao ser movido. Se você move um arquivo para o mesmo lugar em que ele está (mesma pasta), mas modifica o seu nome, você o está renomeando.

Exclusão de um arquivo

Semelhante às pastas, os arquivos também podem ser excluídos. O método de exclusão de arquivos é o Delete(). Ao contrário do método para exclusão de pastas, esse método possui apenas uma versão (assinatura) sem parâmetros.

Como no caso das pastas, é importante ter o cuidado de certificar-se com o usuário que a exclusão deve mesmo ser feita. Veja o código a seguir:

meuArquivo = new FileInfo(@"d:\exemplo.txt");

if (meuArquivo.Exists){ try {

Movimento de um arquivo

Page 8: entrada e saída de arquivos em c# - parte2

if (MessageBox.Show("Tem certeza que deseja excluir o arquivo?", "Confirmação", MessageBoxButtons.YesNo)== DialogResult.Yes) { meuArquivo.Delete(); } } catch (Exception objExcessao) { MessageBox.Show(objExcessao.Message, "Erro"); }}else{ MessageBox.Show("Arquivo inexistente", "Erro");}

Um caso especial: cópia de pastas

Você deve ter reparado que não há um método para copiar pastas. Infelizmente o framework DotNet não fornece esse método para pastas.

Isso não significa que não possamos criar esse método. O que torna essa uma tarefa especial é que pela peculiaridade do sistema de arquivos (sistema hierárquico) precisaremos utilizar um conceito de programação conhecido como recursão.

Isso ocorre porque uma pasta pode conter arquivos e subpastas. Uma subpasta pode conter arquivos e subpastas, e processo segue, até que todo o conteúdo seja copiado.

O que devemos fazer basicamente é criar a pasta destino. Depois copiar os arquivos da pasta origem para dentro da pasta destino. Agora, para cada subpasta da pasta origem devemos criar essa subpasta dentro da pasta destino, copiar os arquivos dela dentro da respectiva cópia na pasta destino e para cada subpasta dela ... Ei! Espera um pouco... Isso não tem fim?

Percebeu que não é uma tarefa simples? Mas você também deve ter percebido que há uma certa repetição na forma como o processo é realizado. Veja:

1. Cria-se a pasta 2. Para cada arquivo da pasta, copia-se o arquivo

3. Para cada pasta, reinicie o processo para essa pasta

Exclusão de um arquivo

Page 9: entrada e saída de arquivos em c# - parte2

O reinício do processo se dá chamando-se a função de cópia da pasta dentro dela mesma, só que para suas subpastas. Quando fazemos uma função que chama a si mesma estamos criando uma função recursiva.

É claro que isso tem que parar, senão teremos um loop infinito de recursão. Mas sabemos que o processo terá uma parada pois não existe pasta com infinitas subpastas.

Agora que você já viu a estratégia, vamos a execução.

Primeiramente temos o método que corresponde ao evento de clique do botão de cópia. Ele utiliza os textos de suas textboxes preenchidas pelo usuário como caminhos para as pastas de origem e de destino. Observe atentamente os comentários:

private void button3_Click(object sender, EventArgs e) { DirectoryInfo pastaOrigem; DirectoryInfo pastaDestino; //valida se as caixas foram preenchidas if (textBox1.Text == "" || textBox2.Text == "") { MessageBox.Show("Informação não preenchida", "Erro"); } else { //verifica se os diretórios são válidos pastaOrigem = new DirectoryInfo(textBox1.Text); pastaDestino = new DirectoryInfo(textBox2.Text);

if (!pastaOrigem.Exists) { MessageBox.Show("Pasta de origem informada não existe", "Erro"); } else { //tudo a partir de agora é feito dentro de um try...catch try { //verifica se a pasta destino é "raiz" if (pastaDestino.Root.Name == pastaDestino.Name) { MessageBox.Show("A pasta destino não pode ser uma pasta raiz", "Erro"); } else { //verifica se a pasta "pai" da pasta destino existe if (!pastaDestino.Parent.Exists)

Page 10: entrada e saída de arquivos em c# - parte2

{ MessageBox.Show("O caminho para a pasta destino não existe", "Erro"); } else { //chama a função que copiará a pasta origem para a pasta destino CopiaPasta(pastaOrigem.FullName, pastaDestino.FullName); MessageBox.Show("Pasta copiada com sucesso", "Aviso"); } } } catch (Exception objExcecao) { MessageBox.Show(objExcecao.Message, "Erro"); } } } }

Como você pode ver, uma função chamada CopiaPasta foi criada para executar a cópia. Essa é tal função recursiva de que falávamos. Observe como ela chama a ela mesma:

void CopiaPasta(string Origem, string Destino) { DirectoryInfo pOrigem, pDestino; pOrigem = new DirectoryInfo(Origem); pDestino = new DirectoryInfo(Destino); try { //cria o diretório de destino se ele não existir if (!pDestino.Exists) { pDestino.Create(); }

//para cada arquivo na pasta origem copia esse arquivo para a pasta destino foreach (FileInfo arquivo in pOrigem.GetFiles()) { arquivo.CopyTo(Path.Combine(pDestino.FullName, arquivo.Name)); }

//para cada pasta na pasta origem copia essa pasta para a pasta destino foreach (DirectoryInfo pasta in pOrigem.GetDirectories()) { string strNomeDestino = Path.Combine(pDestino.FullName, pasta.Name);

Page 11: entrada e saída de arquivos em c# - parte2

//chama a função recursivamente CopiaPasta(pasta.FullName, strNomeDestino); } } catch (Exception objExcessao) { MessageBox.Show(objExcessao.Message, "Erro"); } }

Questões de segurança

Você deve ter observado que sempre que um método de copia, movimento ou exclusão de uma pasta ou arquivo foi chamado, procuramos colocá-lo dentro de um bloco try...catch. Mas se já testamos se a pasta ou arquivo existe, para que tanto cuidado?

Existe uma outra questão deve ser considerada, e por isso utilizamos os blocos try...catch. No sistema operacional Windows, as pastas e os arquivos podem ser protegidos, por questões de segurança, contra cópia, movimento ou exclusão. Se a pasta ou arquivo estiver protegido, a operação falhará e gerará uma exceção. Por isso utilizamos os blocos try...catch.

Só por curiosidade, observe na figura 5, como são dados direitos de cópia, movimento ou exclusão para pastas ou arquivos.

Page 12: entrada e saída de arquivos em c# - parte2

Figura 5. Configurações de segurança para pastas e arquivos