QDir delete all files function?
-
Hi-
I'm wondering if anyone else would find it useful to have a function in QDir (maybe static) that would remove all the files in the directory? This seems like a pretty common thing to do. If so, where does one go to post feature requests? Not sure if this has ever been disucssed before, nothing seemed to come up when I searched...
Seems fairly easy to implement, but it would still be nice to be wrapped in a function.
-
If you want to file a suggestion, you can do on "JIRA":https://bugreports.qt.nokia.com/secure/Dashboard.jspa
-
well a base implementation with skipping undeletable files would make sense. f.e. you write your own installer / uninstaller and want to delete a folder that was shipped with your application. you can be pretty much sure that no one else is using this files.
-
[quote author="Nazgul" date="1316505197"]you can be pretty much sure that no one else is using this files.[/quote]
You can never make any assumption on if and who is using your files!
The virus protection, an indexing service, a loaded shared library, an open command promt, the thumbnailer or icon cache refreshing - there are tons of possibilities which might and will use your files without any notice and will prevent you from deleting them.
-
[quote author="Nazgul" date="1316509755"]and else the number of remaining files[/quote]
or number of remaining files and folders
or pointer to hash or list of remaining files and folders? :)I'm not against general removeAll method completely,
Just I think it must be very smart method,
with signals or with callback for catching problems.
But for small tasks this smart method can seems very difficult way. -
-
The number of remaining files represents the same amount of information as a boolean value which indicates if there are any remaining files.
Yes, there might be situations where a convenient QDir::removeAll() method makes sense. But in most of the situations you will end up in writing code around this method which handles situations where it couldn't remove all.
One of the principles in API design (and probably the one most violated) is to not cover every use case just for convenience, especially if this use case does not fully represent real-life situations encountered - this keeps the API clean and simple. This might be the reason there is no such method in the Qt API in the first place (which does not mean that such a method wouldn't make sense in some situations).
-
Wow... quite a discussion around what I thought was a fairly simple matter. I'm just looking for a function that I use in boost frequently.
http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/reference.html#remove_all
-
[quote author="medvedm" date="1316524223"]Wow... quite a discussion around what I thought was a fairly simple matter. I'm just looking for a function that I use in boost frequently.
http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/reference.html#remove_all
[/quote]You can still use it, you know. Qt and Boost can play nicely together.
-
Further problems can arise with a general DeleteAll. We implemented a method like this, but I can see why it cannot be generalized enough. (Our implementation is purely for cleanup purposes, so it will return false right after the first remove fails or can be specified to skip the failed files if not that important)
Problem 1: what type of files?
We ended with a list-files like this one:
@QFileInfoList files = topDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Hidden | QDir::System/* | QDir::NoSymLinks*/);@The symlinks have to be handled with special care - one of our implementation resolved the symlink files and tried to remove the target - which is in some cases a system directory (like Documents or Music in Windows) or file (like the shutdown.exe)! But in other projects resolving symlinks can be a criteria.
So after we removed the files in the given directory we list the sub-directories like this:
@QFileInfoList dirs = topDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Hidden | QDir::System);@We can remove the System directories because we know it won't be used in directories like "Program Files" or "Windows" (in Windows OSs of course), but it's also cannot be used as a general method because with less care it can make trouble.
And the symlinks to directories have to be handled differently to not to resolve the link, only remove the symlink files to directory (not the target directory)
And of course it's a recursive method which removes the given directory after it removed every files and sub-directories under.
I hope it can demonstrate that there's a lot of use cases and I don't think a general implementation could used in every case. Maybe a delegate or signal/slot based implementation, but I think it's safer to implement your own and give it a proper name indicates where it can be used.
Also our implementation is about 60 lines with conditional debug-logging as well, so it's not that hard to write one, and this way you can ensure (and you have to ensure!) the right usage.
-
I was about to implement it in Qt when I read this discussion... Very interesting.
My first instinct was to reply this:
"I would have stopped on the first error (like KIO does) and returned a bool. But a flag to ignore errors and keep going could indeed be interesting, e.g. for the case of temporary directories, where we just want to clean up as much as possible. This is also what rm -rf appears to do.
I don't see what's "non general" about this. True, it won't do the job for a file manager (who should report more details on errors and provide the user with options), but it will do for many cases of programmatically deleting a dir, like temp dirs."
Temp dirs. But indeed not install dirs (these are more like a file manager operation which should tell the user what couldn't be deleted).
I admit that the use case I have in mind is really temp dirs (I want to add QTemporaryDir to Qt), but putting the remove-recursive code inside the temp-dir class felt wrong, this is why I was looking at putting it in QDir.
However I just looked all over KDE (as an example of a huge code base of libs and apps), and the only non-user-oriented task for removing directories are:
- safe (random-named) temp dirs
- fixed-named temp dirs as used by unittests for easier debugging.
- konqueror sessions which are saved on disk as dirs.
Everything else is user-oriented, which means that it should support
- proper error reporting (telling the user which files couldn't be removed)
- proper progress reporting and even ideally an async job (you don't want to block the application for 10 minutes while deleting a huge dir with huge files)
- network transparency, if possible (which is the case in KDE).
All of this disqualifies a QDir::removeAll method.
In fact, having one at that level would mislead people into using it for user-oriented operations, which would not be good.
Instead I'm now thinking that it should be a static method of the QTemporaryDir class which I'm about to write, so that people can call it on temporary dirs, whether they were created with a random name by the class, or with a fixed name [in unittests]. Technically it means people can still call it in all use cases, but the naming makes it clear that it is meant for small local hidden-from-the-user temp dirs, not for generic user-visible directories.
This is the way it has been in KDE for many years, and I see that it hasn't been abused :-)
Deal?
-
Nice, thanks!