4

My goal is to delete all files in a given folder but not to delete the folder itself. I was thinking of calling FindFirstFile followed by repeated calls to FindNextFile while doing deletion of each file found, using the following pseudo code:

if(FindFirstFile(FindFileData))
{
    do
    {
        DeleteFile(FindFileData.FileName);
    }
    while(FindNextFile(FindFileData));

    FindClose(FindFileData);   //EDIT for people who didn't see my pseudo-code remark
}

But now I'm thinking, if I'm allowed to delete files while doing the enumeration in that folder? Or in other words, do I need to first cache all the file names found and then delete them, or is it OK to do it as I showed above?

c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • 2
    Why don't you test it, and see if it works? – sashoalm Jul 23 '13 at 06:13
  • 1
    @sashoalm: For me it was easier to ask if someone else ran into it. – c00000fd Jul 23 '13 at 06:18
  • why don't you use http://msdn.microsoft.com/en-us/library/bb762164%28v=vs.85%29.aspx as mentioned in the DeleteFile documentation? – Tobias Langner Jul 23 '13 at 06:23
  • I think your error handling for [`FindFirstFile`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx) is wrong. In case of error, it returns `INVALID_HANDLE_VALUE`, which is -1 - so your `if` branch would be entered. – Frerich Raabe Jul 23 '13 at 06:43
  • @c00000fd - Indeed, asking someone else what happened when they did it is going to be less work for you than simply trying it. I suggest that you try something so trivial yourself in the future. Or actually on second thoughts, don't bother - it's better for our job security if you stay lazy. :laugh: – enhzflep Jul 23 '13 at 07:20
  • 1
    @enhzflep: Running a successful test doesn't mean that the code is structured correctly. That is what I am trying to establish here. – c00000fd Jul 23 '13 at 08:49
  • @c00000fd - okay mate. :) First you asked `is it OK to do as I showed above?`. Next, when asked why you don't test it yourself, you replied `easier to ask if someone else ran into it`. Now, in your last comment you're asserting that you're actually asking if the code is structured correctly. Perhaps I was unduly harsh, I'll see how I feel about it next week. Since I'm in a good mood, why do it like this at all? Just make a call to `system`. This example deletes all files in the current directory. Obviously, you could specify the full path. `system("del *.*");` - switch del for rm on *nix. – enhzflep Jul 23 '13 at 09:33
  • @enhzflep Don't use `system`, there's an API for it: `DeleteFile`. He's already using it. – Cody Gray - on strike Jul 23 '13 at 10:08
  • @CodyGray - Thank-you. I've just read http://www.gidnetwork.com/b-61.html and http://stackoverflow.com/questions/1107705/systempause-why-is-it-wrong . Goodness me! I had no idea such an approach was so expensive. :embarrassed: – enhzflep Jul 23 '13 at 12:56

2 Answers2

2

Yes, you can safely delete files from a folder using a traversal on these lines, provided of course that you get the API and logic details right (e.g. Frerich Raabe's comment).

So your FindFirstFile will initialize a WIN32_FIND_DATA structure and your FindNextFile will refer to the same structure for its way-finding purposes. As long as you don't corrupt it you can delete files as you go.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • 1
    Dont forget to pay attention to the details that the `WIN32_FIND_DATA` actually reports. Do not try to call `DeleteFile()` on folders, and also the `cFileName` field is just the filename by itself so you have to manually prepend a complete folder path in front of it when calling `DeleteFile()`. – Remy Lebeau Jul 23 '13 at 20:10
  • @RemyLebeau: Yes, of course. I put a note that the code sample above is just a pseudo-code. – c00000fd Jul 24 '13 at 00:41
  • Do you have any reference to the safety of these deletions? – xuhdev Jan 25 '22 at 21:14
1

FindFirstFile returns a handle that in case it is valid should be released with FindClose.