No artigo anterior mostrei como é fácil criar um programa que remove as subpastas de uma pasta indicada pelo usuário. No código, usamos os recursos disponibilizados pelo .Net Framework, que facilitam muito a nossa vida.
No presente artigo, mostro como obter o mesmo resultado, mas de uma forma um pouco mais “trabalhosa”. Dispensaremos os recursos automáticos de busca por pastas e arquivos, e faremos nossas próprias comparações. Claro, ainda usaremos alguns recursos da linguagem, mas o “cerne” do problema será solucionado por nossa própria conta, usando um pouco de recursão.
Primeiro, crie um novo projeto, baseando-se no artigo anterior para a parte visual.
Agora, vamos às diferenças. O código do evento btRemover_Click deve ficar assim:
private void btRemover_Click(object sender, DirectoryNotFoundException e)
{
if (txtCaminho.Text.Trim() == “”)
{
MessageBox.Show(“Por favor, digite ou selecione uma pasta para procurar.”);
txtCaminho.Focus();
return;
}
else if (cmbCriterios.SelectedIndex == 0)
{
MessageBox.Show(“Por favor, selecione um critério na lista.”);
cmbCriterios.Focus();
return;
}
else if (txtCriterio.Text.Trim() == “”)
{
MessageBox.Show(“Por favor, digite um critério.”);
txtCriterio.Focus();
return;
}
string criterio = txtCriterio.Text;
switch (cmbCriterios.SelectedIndex)
{
case 2:
criterio += “*”;
break;
case 3:
criterio = “*” + criterio;
break;
case 4:
criterio = “*” + criterio + “*”;
break;
}
if (MessageBox.Show(
“Deseja realmente procurar e remover as pastas onde os nomes “
+ cmbCriterios.Text + ” \”” + txtCriterio.Text + “\”?”,
“Confirmar”,MessageBoxButtons.YesNo) == DialogResult.No
)
return;
this.Cursor = Cursors.WaitCursor;
btRemover.Enabled = false;
btRemover.Text = “Por favor, aguarde…”;
pgbRemovendo.Visible = true;
int total = procurarPastas(txtCaminho.Text, criterio, chkSubpastas.Checked);
pgbRemovendo.Visible = false;
this.Cursor = Cursors.Default;
if (total == 0)
MessageBox.Show(“Nenhuma pasta encontrada.”);
else
MessageBox.Show(total.ToString() + ” pasta(s) removida(s).”);
btRemover.Enabled = true;
btRemover.Text = “&Procurar e remover”;
}
Agora, crie a função procurarPastas. Essa função recebe 3 parâmetros:
- o caminho da pasta principal, a partir de onde procuraremos as pastas a serem removidas
- uma máscara para sabermos os critérios selecionados para a procura
- opção de procurar ou não nas subpastas
Novamente, os comentários estão no próprio código:
int procurarPastas(string pastaPai, string maskCriterio, bool recursivo)
{
int total = 0;
DirectoryInfo pasta = new DirectoryInfo(pastaPai);
bool remover = false;
string criterio = maskCriterio.Replace(“*”,“”);
try
{
DirectoryInfo[] subPastas = pasta.GetDirectories();
//percorremos todas as subpastas
foreach (DirectoryInfo subPasta in subPastas)
{
// procurar pastas que contenham o critério selecionado
if (maskCriterio.StartsWith(“*”) && maskCriterio.EndsWith(“*”))
{
if (subPasta.Name.IndexOf(criterio,
StringComparison.InvariantCultureIgnoreCase) >= 0 )
remover = true;
}
// procurar pastas que comecem com o critério selecionado
else if (maskCriterio.StartsWith(“*”))
{
if (subPasta.Name.StartsWith(criterio,
StringComparison.InvariantCultureIgnoreCase))
remover=true;
}
// procurar pastas que terminem com o critério selecionado
else if (maskCriterio.EndsWith(“*”))
{
if (subPasta.Name.EndsWith(criterio,
StringComparison.InvariantCultureIgnoreCase))
remover = true;
}
// procurar pastas que tenham o nome
//exatamente igual ao critério selecionado
else
{
if (subPasta.Name.ToLower() == criterio.ToLower())
remover=true;
}
if (recursivo) // procura nas subpastas da subpasta atual
total += procurarPastas(subPasta.FullName, maskCriterio, recursivo);
if (remover) //removemos a subpasta com todo o seu conteúdo
{
removePasta(subPasta);
total += 1;
}
this.Refresh();
remover = false;
}
}
catch (StringComparison)
{
MessageBox.Show(“Pasta inválida.”);
}
return total;
}
Vamos então ao código da função removePasta. Ela é a responsável por fazer o “trabalho sujo” de eliminar as pastas encontradas. Repare que ela remove os arquivos e subpastas um a um:
void removePasta(DirectoryInfo pasta)
{
foreach (FileInfo arquivo in pasta.GetFiles()) //apaga os arquivos da pasta
{
arquivo.IsReadOnly = false;
arquivo.Delete();
}
//apaga subpastas da pasta atual
foreach (DirectoryInfo subPasta in pasta.GetDirectories())
{
removePasta(subPasta);
}
// e finalmente, apaga a pasta
pasta.Delete();
}
Como pode ver, é possível usar a mesma lógica em outras linguagens.