Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Delete old dirs
Qt 6.12 LTS is out! See what's new in the release blog

Delete old dirs

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 3 Posters 3.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ JonB

    @LeLev
    If I understand you right: I still do not see any sort() call anywhere? So your list is only already correctly sorted because the directories happen to be sorted that way in the order QDirIterator returns them. Which you already knew empirically, but (I think) should not rely on.

    I would expect to see some kind of std::sort(dts). dts contains a list of QDateTimes, so whatever it takes to sort with that data in the list. Bearing in mind I'm not a C++-er, looks like you might use qsort() with some comparer function, e.g. see https://stackoverflow.com/questions/46804220/how-to-sort-qlist-according-to-a-certain-order-not-alphabetical for an example. But it might be that nowadays you should use std::sort(), http://www.cplusplus.com/reference/algorithm/sort/, Qt example in https://evileg.com/en/post/243/.

    ODБOïO Offline
    ODБOïO Offline
    ODБOï
    wrote on last edited by
    #5

    @JonB i edited the code. Thank you again.

    Last question please : the folders i will delete will contain about 6Go of image files, so should i call app.processevents() in my for loop where deletion is done ?

    JonBJ 1 Reply Last reply
    0
    • ODБOïO ODБOï

      @JonB i edited the code. Thank you again.

      Last question please : the folders i will delete will contain about 6Go of image files, so should i call app.processevents() in my for loop where deletion is done ?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #6

      @LeLev
      I'm on holiday so this is my last reply :)

      Yes, you might want to call processEvents() if it's taking a long time (size of files may not matter as much as number of files). It's always a bit naughty calling that, and you may have to keep an eye on other areas of code being re-entered if you do. Or, you might decide that the whole deletion is best done in a thread of its own since it's "standalone"?

      After your code what you have a is a sorted list of dates. You then need to get back to the directory name which needs deleting, you started from that but do not have it now. You either then have to reconstruct the name from the date (nasty/dodgy?), or you should actually create/store/sort a struct for each one containing the date plus the original name. Alternatively you might want to use a QMap or std::map for this (key is date, value is name), e.g. see https://stackoverflow.com/a/26695746. If you use a map (at least QMap, not sure about std::map), you don't ever have to do a sort(), the sorting is done when keys are inserted into the map and so you just iterate the keys and they will already be in sorted order.

      P.S.(!)
      If you feel/find you can trust https://doc.qt.io/qt-5/qdir.html#SortFlag-enum, changing over to QDir::entryList() with QDir::Time instead of QDirIterator, you can avoid all your own sorting. You'd have to test it out on directories under Windows....

      ODБOïO 1 Reply Last reply
      1
      • JonBJ JonB

        @LeLev
        I'm on holiday so this is my last reply :)

        Yes, you might want to call processEvents() if it's taking a long time (size of files may not matter as much as number of files). It's always a bit naughty calling that, and you may have to keep an eye on other areas of code being re-entered if you do. Or, you might decide that the whole deletion is best done in a thread of its own since it's "standalone"?

        After your code what you have a is a sorted list of dates. You then need to get back to the directory name which needs deleting, you started from that but do not have it now. You either then have to reconstruct the name from the date (nasty/dodgy?), or you should actually create/store/sort a struct for each one containing the date plus the original name. Alternatively you might want to use a QMap or std::map for this (key is date, value is name), e.g. see https://stackoverflow.com/a/26695746. If you use a map (at least QMap, not sure about std::map), you don't ever have to do a sort(), the sorting is done when keys are inserted into the map and so you just iterate the keys and they will already be in sorted order.

        P.S.(!)
        If you feel/find you can trust https://doc.qt.io/qt-5/qdir.html#SortFlag-enum, changing over to QDir::entryList() with QDir::Time instead of QDirIterator, you can avoid all your own sorting. You'd have to test it out on directories under Windows....

        ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on last edited by
        #7

        @JonB said in Delete old dirs:

        you started from that but do not have it now

        yes, i just was thinking about a way to implement the mapping between my sorted dates list and the dirs list , and i thought about QMap also, struct one seems nice also. Thank you

        @JonB said in Delete old dirs:

        P.S.(!)
        ...

        i will check also

        1 Reply Last reply
        0
        • ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on last edited by ODБOï
          #8

          finally i did the deletion part with 2 nested for loops. I know this has horrible complexity but for my use case it should feet.
          --the max number of folders will be 4 and every time i will delete only one (oldest)

          void deleteOldDirs2(){
                  QDirIterator it(WORKINGDIR);
                  QStringList pathList;
                  QList <QDateTime> dts;
                  QString format = "ddd MMM d yyyy_hh-mm-ss";
                  while (it.hasNext())
                  {
                      QString name = it.next();
                      pathList<<name;
                  }
                  if(pathList.length()>=4){
                      for(int i = 0; i<pathList.length() ;i++){
                          QDir dir(pathList[i]);
                          if(dir.dirName()!="."&&dir.dirName()!=".."){
                              QDateTime dt = QDateTime::fromString(dir.dirName(),format);
                              if(dt.isValid()){
                                  dts << dt;
                              }
                          }
                      }
                      std::sort(std::begin(dts), std::end(dts));
                      for(int j=0; j<dts.length()-2;j++){ // keep 3 folders (!iterate)
                          //qApp->processEvents(); // ?
                          for(int o=0;o<pathList.length();o++){
                              //qApp->processEvents(); // ?
                              QDir dir(pathList[o]);
                              if(dir.dirName()!="."&&dir.dirName()!=".."){
                                  QDateTime dt = QDateTime::fromString(dir.dirName(),format);
                                  if(dt.isValid()){
                                      if(dts[j]==dt){
                                          qDebug()<<"Deleting : " << dir;
                                          dir.removeRecursively();
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
          

          I wonder if i have to uncomment the qApp->processEvents() calls, there is maybe 30-40000 files in each folder

          J.HilkJ 1 Reply Last reply
          0
          • ODБOïO ODБOï

            finally i did the deletion part with 2 nested for loops. I know this has horrible complexity but for my use case it should feet.
            --the max number of folders will be 4 and every time i will delete only one (oldest)

            void deleteOldDirs2(){
                    QDirIterator it(WORKINGDIR);
                    QStringList pathList;
                    QList <QDateTime> dts;
                    QString format = "ddd MMM d yyyy_hh-mm-ss";
                    while (it.hasNext())
                    {
                        QString name = it.next();
                        pathList<<name;
                    }
                    if(pathList.length()>=4){
                        for(int i = 0; i<pathList.length() ;i++){
                            QDir dir(pathList[i]);
                            if(dir.dirName()!="."&&dir.dirName()!=".."){
                                QDateTime dt = QDateTime::fromString(dir.dirName(),format);
                                if(dt.isValid()){
                                    dts << dt;
                                }
                            }
                        }
                        std::sort(std::begin(dts), std::end(dts));
                        for(int j=0; j<dts.length()-2;j++){ // keep 3 folders (!iterate)
                            //qApp->processEvents(); // ?
                            for(int o=0;o<pathList.length();o++){
                                //qApp->processEvents(); // ?
                                QDir dir(pathList[o]);
                                if(dir.dirName()!="."&&dir.dirName()!=".."){
                                    QDateTime dt = QDateTime::fromString(dir.dirName(),format);
                                    if(dt.isValid()){
                                        if(dts[j]==dt){
                                            qDebug()<<"Deleting : " << dir;
                                            dir.removeRecursively();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            

            I wonder if i have to uncomment the qApp->processEvents() calls, there is maybe 30-40000 files in each folder

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #9

            @LeLev
            you can easily move that into a thread

            //Where you would call deleteOldDirs2
            
            QThread *t = QThreat::create(deleteOldDirs2);
            t->start();
            

            emit a signal once your deleteOldDirs2 returns to delete the QThread object and you're done.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            ODБOïO 1 Reply Last reply
            1
            • J.HilkJ J.Hilk

              @LeLev
              you can easily move that into a thread

              //Where you would call deleteOldDirs2
              
              QThread *t = QThreat::create(deleteOldDirs2);
              t->start();
              

              emit a signal once your deleteOldDirs2 returns to delete the QThread object and you're done.

              ODБOïO Offline
              ODБOïO Offline
              ODБOï
              wrote on last edited by ODБOï
              #10

              hi
              @J.Hilk said in Delete old dirs:

              //Where you would call deleteOldDirs2

              i call it in the ctor of the same class,
              So i tryed

                QThread *th = QThread::create(deleteOldDirs2);
                  th->start();
              
              

              but output is :
              erreur : reference to non-static member function must be called; did you mean to call it with no arguments?
              erreur : no matching function for call to 'create'
              C:\Qt\5.12.0\mingw73_64\include\QtCore\qthread.h:174: candidate template ignored: substitution failure [with Function = void, Args = <>]: cannot form a reference to 'void'

              Do you know what the problem is ?

              @J.Hilk said in Delete old dirs:

              = QThreat

              a slip ? :D

              edit i just tryed with a static function and it works, but my function can't be static because i need to access some members

              J.HilkJ 1 Reply Last reply
              0
              • ODБOïO ODБOï

                hi
                @J.Hilk said in Delete old dirs:

                //Where you would call deleteOldDirs2

                i call it in the ctor of the same class,
                So i tryed

                  QThread *th = QThread::create(deleteOldDirs2);
                    th->start();
                
                

                but output is :
                erreur : reference to non-static member function must be called; did you mean to call it with no arguments?
                erreur : no matching function for call to 'create'
                C:\Qt\5.12.0\mingw73_64\include\QtCore\qthread.h:174: candidate template ignored: substitution failure [with Function = void, Args = <>]: cannot form a reference to 'void'

                Do you know what the problem is ?

                @J.Hilk said in Delete old dirs:

                = QThreat

                a slip ? :D

                edit i just tryed with a static function and it works, but my function can't be static because i need to access some members

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #11

                @LeLev auto complete corrects QThread to Thread, every time x)

                Well, member access in a threaded function is a bad idea, you could capture them and pass them as arguments ?

                That would work.


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                ODБOïO 1 Reply Last reply
                1
                • J.HilkJ J.Hilk

                  @LeLev auto complete corrects QThread to Thread, every time x)

                  Well, member access in a threaded function is a bad idea, you could capture them and pass them as arguments ?

                  That would work.

                  ODБOïO Offline
                  ODБOïO Offline
                  ODБOï
                  wrote on last edited by ODБOï
                  #12

                  @J.Hilk
                  sorry! i'm actually not accessing any member at all in that function, so i made it static, and it works, now i will try to see how to emit a signal from it to delete the qthread
                  thank you

                  J.HilkJ 1 Reply Last reply
                  1
                  • ODБOïO ODБOï

                    @J.Hilk
                    sorry! i'm actually not accessing any member at all in that function, so i made it static, and it works, now i will try to see how to emit a signal from it to delete the qthread
                    thank you

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #13

                    @LeLev keep me posted, I haven't used the create function of QThread jet, bu it should be more lightweight that QtConCurrent, which would be your other alternative.


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    ODБOïO 1 Reply Last reply
                    1
                    • J.HilkJ J.Hilk

                      @LeLev keep me posted, I haven't used the create function of QThread jet, bu it should be more lightweight that QtConCurrent, which would be your other alternative.

                      ODБOïO Offline
                      ODБOïO Offline
                      ODБOï
                      wrote on last edited by
                      #14

                      @J.Hilk
                      i can't not find a way to emit a signal from the static function..
                      but i think simply delaying the deletion of the QThread is enought for my usecase, deleteOldDirs2() will take 5-s seconds maximum (+the object is created only once and the app will restard automatically every 5 hours so no memory increase).

                         QThread *th = QThread::create(deleteOldDirs2); 
                         th->start();
                         QTimer::singleShot(20000, [=]() { // 20sec must be safe 
                              th->deleteLater();
                         });
                      
                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt
                      • Unsolved