Split file system path (QString) into folder hierarchy



  • Here's what I want to do. I have a path, e. g.
    C:/Users/Admin/AppData/Temp/
    What I want to get is the list of my path's parent folder, that folder's parent folder and so on up to the root entry:
    C:/Users/Admin/AppData/
    C:/Users/Admin/
    C:/Users/
    C:/

    For added fun, this is for a cross-platform app that runs both on Windows and POSIX systems (Linux / Mac OS X).

    I'm tempted to simply split the path using '/' for separator, but I'm afraid that will not be a universal solution and may fail on some weird paths. Windows UNC path (starts with "\?") is one thing that comes to mind, and I'm sure there are other special cases I'm not aware of.

    Another idea I've had is QDir(path).cdUp(), but the problem with that is that cdUp returns false and does nothing if the target folder doesn't exist. And for my application I need this to work for non-existing folders just as well.

    So, is there a Qt way to do what I want? If not and I must implement it all myself, can you recall any other special cases I'd have to handle?


  • Moderators

    QFileinfo might be of use here. Something like this should work (or at least be a good starting point):

    QStringList directoryList(const QString& str) {
        auto path = QDir::cleanPath(str);
        QStringList result(path);
        while(!QFileInfo(path).isRoot())
            result << (path = QFileInfo(path).path());
        return result;
    }
    


  • I don't think any direct function/method exist like this.
    May be you can try with QDir::Seperator().. and QString split to make it work across the platform ?



  • Neat trick, Chris, thanks! I didn't think of fooling QFileInfo into treating folder name like a file name and using path().
    Is there a slightest possibility that isRoot() will never be true in this algorithm (assuming any garbage input is theoretically possible)? It looks a little dangerous. I should probably also check path for isEmpty() in the loop condition?


  • Moderators

    Yeah, that's why this was a starting point. isRoot() sure wouldn't work for garbage or even something credible like http://....
    A second thought would be to check instead if we managed to peel something off of the path, e.g.

    QStringList foo(const QString& str) {
        auto path = QDir::cleanPath(str);
        QStringList result(path);
        while((path = QFileInfo(path).path()).length() < result.last().length())
            result << path;
        return result;
    }
    

    This way we guarantee it won't fall into infinite loop. This should also handle garbage reasonably.

    As for the trick - it's not really a trick. It's actually documented in the dir method but (maybe through omission) is just not mentioned for path, which is a shame.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.