Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tri sur dossier

Suppression dossier ancien

    31 décembre 2019 à 11:22:42

    Bonjour à tous.

    Tout jeune sur ce site et en pleine découverte des possibilités du langage C++.

    Pour info : Je crée un programme sur CodeBlocks qui exécute un logiciel avec ShellExecute(). Ce logiciel crée une arborescence de dossier et y met des fichiers au format .pdf . Exemple : c:\...\dossier\31_12_2019_09_15\ 0 (Liste des documents)\ fichiers.pdf .

    Il y a entre 3 et 4 dossier (31_12_2019_09_15) généré par jour avec leurs sous dossiers (0 (Liste des documents)) et fichiers (.pdf).

    Je souhaiterai supprimer les DOSSIERS (31_12_2019_09_15) vieux de plus de X jours.

    Plus tard dans mon développement, je souhaiterai déplacer mes fichiers .pdf de un cran dans cette arborescence.

    Need Help pour créer une fonction.

    Merci d'avance.

    Stef !!

    • Partager sur Facebook
    • Partager sur Twitter
      31 décembre 2019 à 17:58:43

      Bonjour bonjour,

      La solution la plus simple a implementer me paraitrait de parcourir tous les dossiers et de checker a chaque fois leurs dates de creation, puis de supprimer tout les dossiers ne respectant pas ta condition.

      N'hesites pas si tu veux que je precise,

      • Partager sur Facebook
      • Partager sur Twitter

      “Any fool can write code that a computer can understand.

      Good programmers write code that humans can understand.” -- Martin Fowler

        2 janvier 2020 à 8:13:39

        Bonjour à vous 2.

        Merci pour vos remarques.

        Tellement d'informations que je m'y perd. J'ai compris l'idée mais le montage du code est plus complexe. J'ai suivi la piste du SHFileOperationA et autres qui semblent intéressantes.

        J'aimerai avoir un exemple si possible se rapprochant de mon intention ? L'idée de comparer la date de création du dossier (31_12_2019_09_15) et la date du jour me semble intéressante. Peut être y a t'il plus simple.

        Merci

        -
        Edité par StefMuss 2 janvier 2020 à 9:33:44

        • Partager sur Facebook
        • Partager sur Twitter
          3 janvier 2020 à 0:52:08

          Vous parlez de trucs différents (date de création, date de mise à jour, etc...) et qui varient en fonction du type de système de fichier.

          Pouvez-vous être plus spécifiques ?

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            3 janvier 2020 à 8:22:46

            Bonjour , Oui bien sur !!

            Après réflexion, je privilégierai plutôt un tri sur le nom (vu son format = 31_12_2019_09_15 ( 0 )     ). Oui y 'a bien un " ( 0 )" a la fin et dois aussi faire avec :( ... C'est peut être moins simple a coder mais je valide cette solution. Autour y aura d'autres logiciels qui interféreront et très souvent les attributs changent. Le nom du dossier lui fera "preuve" de date de création.

            Le hic est de convertir et donc faire des opérations avec des valeurs de la structure dirent->d_name (char) avec un int de la structure tm.

            Merci encore,

            -
            Edité par StefMuss 3 janvier 2020 à 9:39:46

            • Partager sur Facebook
            • Partager sur Twitter
              3 janvier 2020 à 11:28:24

              Salut,

              Donc ça revient à faire une analyse de chaine ? Convertir ta chaine "31_12_2019_09_15" en date ? Si c'est toujours comme ça, un petit sscanf pour remplir une structure, et après on trie selon la structure ?

              -
              Edité par Fvirtman 3 janvier 2020 à 11:28:55

              • Partager sur Facebook
              • Partager sur Twitter

              Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                3 janvier 2020 à 12:27:21

                Fvirtman = Alors si on as la même définition du terme "analyse de chaine" ==>OUI. Mais difficile de faire une opération sur ces éléments (sauf si après conversion la fonction mktime me permet de tester.)

                Si tu as un bout de code a tester pour que je regarde si cela colle, ce serai sympa.

                Merci,



                • Partager sur Facebook
                • Partager sur Twitter
                  3 janvier 2020 à 13:13:22

                  Alors je vais te proposer un bout de code qui contient un peu de C (sscanf) et du C++, c'est un peu bâtard entre deux langages, mais sscanf est puissante.

                  (pas testé, je fais ça de tête il faudra peut être adapter)

                  Soit tachaine = "31_12_2019_09_15"

                  // transformation d'une chaine (tachaine) en tableau lexicographique
                  
                  std::vector<int> datetime;
                  datetime.resize(5); // année, mois, jour, heure, minute
                  // toi tu as jour,mois,année,heure,minute
                  sscanf(tachaine.c_str(),"%d_%d_%d_%d_%d_%d",&datetime[2],&datetime[1],&datetime[0],&datetime[3],&datetime[4]);

                  A la sortie, tu as datetime = [2019,12,31,9,15]

                  Du coup, après, tu compares tes tableaux datetime ou l'année est d'abord, puis le mois, puis le jour, puis l'heure, puis les minutes, donc il suffit de comparer, le plus fort d'abord : on parle de comparaison lexicographique :

                  Pour comparer datetime1 et datetime2 par exemple :

                  std::lexicographical_compare(datetime1.begin(),datetime1.end(),datetime2.begin(),datetime2.end());

                  te renvoie true ou false si datetime1 < datetime2 

                  Tu peux ensuite, si tu en a plusieurs, faire un tri selon l'ordre lexicographique :

                  https://stackoverflow.com/questions/16463008/sort-by-lexicographical-compare-function




                  -
                  Edité par Fvirtman 3 janvier 2020 à 13:16:28

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                    3 janvier 2020 à 16:31:37

                    Fvirtman merci pour ta proposition. Je souhaite "trier" pour supprimer les dossiers vieux de X jours. D'ailleurs pas besoin de prendre en compte l'heure.

                    A l'étape ou je suis je dispose de 2 tableaux de char (datedujour et nomDossier) au format AAAAMMJJ (que je réutilise plus tard dans mon programme). Chaque case des tableaux[i] comprend un chiffre (le 3 de 31 par exemple qui serai dans l'avant dernière case). Voilà le contenu de mes tableaux :
                    datedujour[9]=20200103 //tableau de char
                    nomDossier[9]=20191231 //tableau de char

                    Je n'ai pas repris ta solution car je n'arrive pas a l'adapter. Mon exemple est pas mal car année, mois et jour sont différents et couvrent donc plus ou moins toutes les possibilités.

                    Merci



                    -
                    Edité par StefMuss 3 janvier 2020 à 16:32:21

                    • Partager sur Facebook
                    • Partager sur Twitter
                      7 janvier 2020 à 11:20:06

                      >Je souhaite "trier" pour supprimer les dossiers vieux de X jours.

                      Ce n'est donc pas un tri mais un filtre qu'il vous faut, non ?

                      Pouvez-vous donner un extrait plus conséquent de votre code car j'ai du mal à voir où est votre difficulté.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        7 janvier 2020 à 12:26:42

                        bacelar


                        Un filtre oui pardon. Voici l'idée de base :

                        J'initialise tout d'abord une variable s_now avec la date du jour

                        time_t now = time(NULL);             // lire l'heure courante
                        struct tm tm_now = *localtime(&now); //convertion locale
                        const time_t* timer;
                        char s_now[sizeof "JJ/MM/AAAA"];     // Creer une chaine 
                        strftime(s_now, sizeof s_now, "%d/%m/%Y", &tm_now); 
                        

                        Je veux supprimer les dossiers vieux de 7 jours en me basant sur le nom du dossier (JJ_MM_AAAA_HH_MM ( 0 ). Je lie donc le nom des dossier.

                        DIR * rep = opendir("C:\\...\\dossier");
                        struct dirent * nomDossier;
                        
                        while ((nomDossier = readdir(rep)) != NULL)
                                {
                                 printf("%s\n", nomDossier->d_name); //pour contrôle visuel de la chaîne
                        //C'est ici que je ne sais plus comment faire }


                        J’espère être lisible. C'est dans la boucle While que je vais devoir coder mon action mais je bloque sur la méthode.

                        Merci

                        -
                        Edité par StefMuss 7 janvier 2020 à 12:27:19

                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 janvier 2020 à 14:19:41

                          Votre code ressemble bien plus à du C qu'à du C++.

                          Quand c'est faisable, restez le plus possible avec le C++.

                          Vous convertissez des dates en chaine de caractère.

                          Vous devez des opérations sur le temps (>7jours par exemple), c'est donc l'opération inverse que vous devez faire : chaine de caractère vers date.

                          Ainsi, vous pourrez facilement faire des comparaisons et savoir si le répertoire doit être supprimé sans aucune autre opération que de comparer la date actuelle et la conversion en date du nom du fichier.

                          Pour créer un "tm" à partir des valeurs AAAA, MM, et DD :

                          https://www.tutorialspoint.com/cplusplus/cpp_date_time.htm

                          Regardez la fonction "difftime" dans le même article.

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                            7 janvier 2020 à 16:28:38

                            J'ai clairement compris ce que je dois faire (me contredire si nécessaire) : transformer s_now et nomDoss en date pour ensuite calculer la différence entre les 2 dates.

                            Revoici mon code modifié :

                            int main()
                            {
                             time_t now = time(NULL);
                             struct tm tm_now = *localtime(&now);
                             int i,TAILLE=sizeof "JJ/MM/AAAA";
                             char s_now[TAILLE]={0};char nomDoss[TAILLE]={0};
                             strftime(s_now, TAILLE,"%d_%m_%Y", &tm_now); //JJ/MM/AAAA:HH:MM:SS
                             cout<<s_now<<endl;              /* A ce stade s_now = {JJ_MM_AAAA} d'aujourd'hui */
                            
                             DIR * rep = opendir("C:\\...\\dossier");
                             struct dirent * nomDossier;
                             while ((nomDossier = readdir(rep)) != NULL)
                                    {
                                     for (i=0;i<=9;i++)
                                         {nomDoss[i]=nomDossier->d_name[i];}
                                     cout<<nomDoss<<endl;    /* A ce stade nomDoss = {JJ_MM_AAAA} du nom de dossier */
                                     .........PANNE D ENCRE...........
                            } }

                            Je bloque au niveau de ma PANNE D ENCRE. Soit ce n'est pas strftime() qu'il faut utiliser pour transformer en date, soit je ne connais pas la bonne syntaxe. asctime() fait le travail inverse que je recherche.

                            Merci pour l'aide.

                            -
                            Edité par StefMuss 7 janvier 2020 à 16:50:54

                            • Partager sur Facebook
                            • Partager sur Twitter
                              8 janvier 2020 à 10:53:55

                              > transformer s_now et nomDoss en date

                              Si par date, vous voulez dire une structure tm, oui.

                              Donc, s_now, on s'en fout, sauf, peut-être pour de l'affichage à la C (beurk), tm_now contient déjà tout ce qu'il faut.

                              Il faut juste que vous transfériez les infos contenus dans "nomDossier->d_name" dans une structure tm, pour enfin appeler "difftime"

                              constexpr double seven_days = 7 * 24 * 60 * 60;
                              
                              ...
                              
                              int main()
                              {
                              ...
                                  while((nomDossier = ....)
                                  {
                                      struct tm tm_fichier = {0};
                              
                                      /* comme l'API C est toute moisie, code foireux, à vérifier */
                              
                                      strptime(nomDossier->d_name,"%d_%m_%Y",&tm_fichier);
                              
                                      if( difftime(tm_now,tm_fichier) > seven_days)
                                      {
                                          ...
                                      }
                              ...
                              }



                              • Partager sur Facebook
                              • Partager sur Twitter
                              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                8 janvier 2020 à 12:20:41

                                j'ai l'erreur strptime was not declared in this scope.... et pourtant j'ai bien time.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  8 janvier 2020 à 14:07:52

                                  cf. doc : http://www.cplusplus.com/reference/ctime/strftime/

                                  Il faut ajouter un "#include <ctime>".

                                  Et il manque le 2ème paramètre dans mon code.

                                  strptime(nomDossier->d_name,10,"%d_%m_%Y",&tm_fichier);

                                  -
                                  Edité par bacelar 9 janvier 2020 à 10:21:00

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                    9 janvier 2020 à 17:43:16

                                    J'ai décidé de passer au plan B car je n'y arrive pas. Je tenez a vous montrer le résultat.

                                    J'ai trouvé une fonction que j'ai adapté a mon utilisation :

                                    int GetNumberDaysBetween2Dates(char *date1, char *date2) {
                                     struct tm timestamp1,timestamp2;
                                     sscanf(date1,"%i-%i-%i",&timestamp1.tm_year,&timestamp1.tm_mon,&timestamp1.tm_mday);
                                     sscanf(date2,"%i-%i-%i",&timestamp2.tm_year,&timestamp2.tm_mon,&timestamp2.tm_mday);
                                     timestamp1.tm_sec = timestamp1.tm_min = timestamp1.tm_hour = timestamp1.tm_yday = timestamp1.tm_isdst = 0;
                                     timestamp1.tm_year -= 1900;
                                     timestamp1.tm_mon--;
                                     timestamp2.tm_sec = timestamp2.tm_min = timestamp2.tm_hour = timestamp2.tm_yday = timestamp2.tm_isdst = 0;
                                     timestamp2.tm_year -= 1900;
                                     timestamp2.tm_mon--;
                                     return abs(mktime(&timestamp2) - mktime(&timestamp1))/86400;
                                    }
                                    

                                    Quand je l'appelle, je lui passent mes valeurs initiales à savoir : s_now et nomDoss (remis au bon format).

                                    Cela fonctionne quasiment ;)... j'ai une incohérence de résultat lorsque on est a cheval sur 2 années.

                                    Exemple : dossier 25-12-2019 et date du jour 09-01-2020 il me retourne 6 jours (du 25 au 31 décembre). Donc FAUX // j'y bosse !!

                                    Merci à tous pour l'aide.



                                    -
                                    Edité par StefMuss 9 janvier 2020 à 17:58:40

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      9 janvier 2020 à 17:55:54

                                      Vous vous prenez la tête juste parce que vous ne voulez pas faire un simple "#include" de "<ctime>" ???

                                      Vous faites ce que je vous est proposé, créer "timestamp1" et "timestamp2" pour pouvoir utiliser la fonction "difftime", mais au lieu d'utiliser cette fonction toute faite vous vous prenez la tête avec des "abs" de mktime divisée par une valeur en dur bien dégueu.

                                      Franchement, vous cherchez vraiment la complexité.

                                      P.S.: le bug est ligne 7 et 10 parce que vous ne gérez pas correctement les cas aux limites, mais laissez tomber ce code tout moisi.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                        10 janvier 2020 à 10:45:15

                                        Merci pour votre avis Bacelar !! droit et efficace !!

                                        Je ne l'ai pas fait avec ctime parceque j'ai toujours le message d'erreur avec strptime. Ne parvenant pas à le résoudre je suis passé au plan B.

                                        Mais votre jugement qualifié m'intéresse et si vous souhaitez m'aider (pour apprendre) je veux bien. D'ailleurs je vais revoir mon code, vous avez raison.

                                        Merci ;)

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          10 janvier 2020 à 10:52:29

                                          Ooups, j'ai croisé les files. :-°

                                          C'est vraiment la merde les API C, vive le vrai C++. ^^

                                          Utilisez "strftime" et pas "strptime".

                                          Désolé.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                            10 janvier 2020 à 14:01:59

                                            bacelar a écrit:

                                            C'est vraiment la merde les API C, vive le vrai C++. ^^ ======> Comment fais t'on pour distinguer une commande ou méthode d'écrire apaprtient au C ou C++ ?? (j'ai appris le C il y a 7 ans de cela et jamais pratiqué et je reprend maintenant (sans que ce soit mon boulot)).

                                            Utilisez "strftime" et pas "strptime". ========> strf = datetime to string, strp = string to datetime.

                                            Désolé ========> Pas de soucie

                                            A chaque fois que je peux, je reprendrai mon code et le ferai propre et 100% c++ et portable (avec votre aide :) ).

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              10 janvier 2020 à 18:23:24

                                              >Comment fais t'on pour distinguer une commande ou méthode d'écrire apaprtient au C ou C++ ??

                                              Si la fonction est déclaré dans un header commençant par un "c" (comme <ctime>), c'est que c'est un "portage" C++ d'une fonction C.

                                              >strf = datetime to string, strp = string to datetime

                                              re Ooups, fatigué, moi.

                                              Je viens de remarquer que "srtptime" est Posix/Linux Only, pas Windows.

                                              https://stackoverflow.com/questions/321849/strptime-equivalent-on-windows

                                              J'ai l'impression que vos sscanf feront bien l'affaire, quitte à bien vérifier les bornes des valeurs (à vous les joies des années bissextiles et des fuseaux horaires).

                                              Mais Google est notre ami :

                                              https://stackoverflow.com/questions/667250/strptime-in-windows

                                              En attendant que C++ donne les outils des manipulations des dates plus modernes. (Ou ça existe déjà ???)

                                              Si vous insistez à le faire vous-même, vérifiez ligne 7 et 10 de ne pas tomber à 0, sinon vous devez calculer le décalage sur l'année d'avant (0=>12).

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                10 janvier 2020 à 19:38:33

                                                > En attendant que C++ donne les outils des manipulations des dates plus modernes. (Ou ça existe déjà ???)

                                                std::chrono::parse ou std::chrono::from_stream (C++20). L'auteur du papier sur les dates à aussi la lib complète sur son github.

                                                Sinon, il y a toujours std::get_time qui est en gros un strptime().

                                                EDIT: ah bah une des solutions sur le thread stackoverflow utilise std::get_time.

                                                -
                                                Edité par jo_link_noir 10 janvier 2020 à 19:40:56

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  11 janvier 2020 à 22:14:04

                                                  Cool !
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                                                  Tri sur dossier

                                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                  • Editeur
                                                  • Markdown