Removendo subpastas. Parte 2 – uma forma mais "primitiva"

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:

  1. o caminho da pasta principal, a partir de onde procuraremos as pastas a serem removidas
  2. uma máscara para sabermos os critérios selecionados para a procura
  3. 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.