wxDev.fr, le portail francophone consacré à wxWidgets ! ( The french portal for wxWidgets )  
Esp. membre
Recheche rapide



Recherche avancée
Statistiques
Membres inscrits :2359

Membres en ligne : 0
Invités en ligne : 8
Pub hébergeur
Pourquoi cette pub ?

Valid XHTML 1.0 Transitional

Valid CSS2

Menu Snippets (navigation):
Pages: 1    Accueil » Snippets » Fichiers - Dossiers - Disques
» [wxRecursRmDir] Fonction récursive pour supprimer une arborescence
Détails du snippet : [wxRecursRmDir] Fonction récursive pour supprimer une arborescence
Informations sur l'auteur de ce snippet :


Hors ligne
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1364
Snippets: 25
Tutoriels: 6
Introduction / Description :
Hello

J'ai récemment eut besoin d'une fonction pour supprimer un dossier et tout son contenu.

Malheureusement, la fonction wxRmDir ne permet que de supprimer un dossier vide.

Après quelques recherches sur le net (j'avais un peu la flemme de la faire moi-même), je suis tombé sur ceci.

Je vous en propose donc une version simplifiée (j'ai supprimé quelques wxLogError) , compatible avec Unicode (ce qui n'est pas le cas dans le code d'origine), avec des commentaires en français.
Contenu du snippet :
Pour pouvoir utiliser cette fonction dans votre code, il faut inclure les déclarations des classes wxDir et wxFileName :

Code wxWidgets:

#include <wx/dir.h>
#include <wx/filename.h>


Et voici maintenant la fonction proprement dite :

Code wxWidgets:

bool wxRecursRmDir(wxString rmDir)
{
    // Par sécurité, on ne vide pas un disque complet
    if (rmDir.length() <= 3) return false;
    // On s'assure que le répertoire à supprimer existe
    if(!wxDir::Exists(rmDir)) return false;
    // On s'assure que le nom du dossier à supprimer se termine bien par un séparateur
    if (rmDir[rmDir.length()-1] != wxFILE_SEP_PATH) rmDir += wxFILE_SEP_PATH;
    // Création de l'objet wxDir
    wxDir* dir = new wxDir(rmDir);
    // Si problème d'allocation, on sort
    if (dir == NULL) return false;
    // Variable temporaire pour les noms de fichiers à supprimer
    wxString filename;
    // Récupération du premier élément présent dans le dossier à supprimer
    bool cont = dir->GetFirst(&filename);
    // Si on a trouvé quelque chose
    if (cont)
    {
        do
        {
            // Si l'élément trouvé est un répertoire
            if (wxDirExists(rmDir + filename))
            {
                // On le supprime
                wxRecursRmDir(rmDir + filename);
            } else {
                // Sinon, on supprime le fichier
                if(!wxRemoveFile(rmDir + filename))
                {
                    // Erreur lors de la suppression (droits d'accès ?)
                    wxLogError(_T("Could not remove file \"") + rmDir + filename + _T("\""));
                }
            }
        }
        // On passe au fichier suivant
        while (dir->GetNext(&filename));
    }
    // Désormais, le dossier est vide, on va donc pouvoir le supprimer
    // Mais il faut d'abord détruire la variable wxDir qui pointe toujours dessus
    delete dir;
    // On peut maintenant supprimer le dossier passé en paramètres
    if (!wxFileName::Rmdir(rmDir))
    {
        // Une erreur est toujours possible (droits d'accès)
        wxLogError(_T("Could not remove directory \"") + rmDir + _T("\""));
        // On indique que tout ne s'est pas bien passé
        return false;
    } else {
        // On indique que tout s'est bien passé
        return true;
    }
}
Explications finales :
Je le répète : le code d'origine n'est pas de moi, mais a été pris sur le forum officiel wxWidgets à cette adresse.

Bonne continuation à tous, et @+

Xav'
Commentaires
etrange02 (Membre)
Lieu: Nantes
Inscrit le : 24-07-2009
Messages: 23
Snippets: 0
Tutoriels: 0
Site web
Hors ligne
Vraiment intéressant comme code. Une autre façon de faire serait d'utiliser un wxDirTraverser, enfin c'est une piste

Code wxWidgets:

//La fonction de suppression
bool SupprimeRepertoire(wxString nom)
{
    if (!wxDirExists(nom))
        return false;
 
    wxArrayString tableau;
    wxDir dir(nom);
    wxDirTraverserSuppression traverser(nom, tableau);
    dir.Traverse(traverser);
 
    size_t i = tableau.GetCount();
    while(i>1)
    {
        wxRmdir(tableau[i-1]);
        i--;
    }
 
 
    if (wxRmdir(tableau[0]))//Vérification finale, seul un dossier vide peut être supprimé
    {
        tableau.Empty();
        return true;
    }
    else
    {
        tableau.Empty();
        return false;
    }
}
 
//La déclaration de wxDirTraverserSuppression dans le header
class wxDirTraverserSuppression : public wxDirTraverser
{
    public:
        wxDirTraverserSuppression(wxString origine, wxArrayString &tableau);
        virtual wxDirTraverseResult OnFile(const wxString &filename);
        virtual wxDirTraverseResult OnDir(const wxString &dirname);
 
    private:
        wxString m_origine;
        wxArrayString &m_tableau;
};
 
//Implémentation de wxDirTraverserSuppression dans le fichier source
 
wxDirTraverserSuppression::wxDirTraverserSuppression(wxString origine, wxArrayString &tableau): m_tableau(tableau)
{
    m_origine = origine;
    tableau.Add(m_origine);//On ajoute le fichier d'origine
}
//Pendant que l'on supprime les fichiers, on enregistre les noms de dossier
wxDirTraverseResult wxDirTraverserSuppression::OnFile(const wxString &filename)
{
    wxRemoveFile(filename);
    return wxDIR_CONTINUE;
}
 
wxDirTraverseResult wxDirTraverserSuppression::OnDir(const wxString &dirname)
{
    m_tableau.Add(dirname);//Suivie des autres noms de dossier
    return wxDIR_CONTINUE;
}
gafatoa (Nouveau membre)
Inscrit le : 15-12-2010
Messages: 1
Snippets: 0
Tutoriels: 0
Hors ligne
Bonjour,

Juste pour signaler que dans wx 2.9.1, une fonction de la classe wxFileName permet d'arriver au meme resultat:
static bool wxFileName::Rmdir( const wxString &dir, int flags = 0 )
(flags wxPATH_RMDIR_FULL or wxPATH_RMDIR_RECURSIVE)
Menu Snippets (navigation):
Pages: 1    Accueil » Snippets » Fichiers - Dossiers - Disques
» [wxRecursRmDir] Fonction récursive pour supprimer une arborescence