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 thatcdUp
returnsfalse
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?
-
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 ? -
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; }
Neat trick, Chris, thanks! I didn't think of fooling
QFileInfo
into treating folder name like a file name and usingpath()
.
Is there a slightest possibility thatisRoot()
will never betrue
in this algorithm (assuming any garbage input is theoretically possible)? It looks a little dangerous. I should probably also checkpath
forisEmpty()
in the loop condition? -
Yeah, that's why this was a starting point.
isRoot()
sure wouldn't work for garbage or even something credible likehttp://...
.
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.