Recursively remove a directory using C

2019-07-19 06:39发布

问题:

I want to implement this myself and I come up something like this:

/* DIR *opendir(const char *name);
 *
 * Open a directory stream to argv[1] and make sure
 * it's a readable and valid (directory) */
if ((dip = opendir(argv[1])) == NULL)
{
        perror("opendir");
        return 0;
}

printf("Directory stream is now open\n");

/*  struct dirent *readdir(DIR *dir);
 *
 * Read in the files from argv[1] and print */
while ((dit = readdir(dip)) != NULL)
{
        printf("\n%s", dit->d_name);
        remove(dit->d_name);
}

I am guessing I have to start delete things from the deepest level and then go up, but now it seems readdir does not give me that order.

Please help, thanks!

回答1:

You have to recurse all the way down to the lower levels first, as in the following pseudo code:

def delDir (d):
    # Delete the directories by recursion, files straight away.

    for every item in d:
        if item is a directory:
            delDir (item)
        else:
            delete file item

    # Finally, remove the directory itself.

    remove directory d

That's it really, this guarantees that all lower directories and files are deleted before you attempt to remove the parent.


Since item is likely to be just the current component of the directory, you may need to construct a full name using, for example, strcpy/strcat:

def delDir (dirName):
    def localBuff[enoughSpace]

    # Delete the directories by recursion, files straight away.

    dirHandle = dirOpen (dirName)
    itemName = dirnext (dirHandle)
    while itemName is valid:
        if itemName <> "." and itemName <> "..":
            strcpy dirName to localBuff
            strcat "/" to localBuff
            strcat itemName to localBuff

            if itemName is a directory:
                delDir (localBuff)
           else:
                delete file localBuff

        itemName = dirnext (dirHandle)

    dirClose (dirHandle)

    # Finally, remove the directory itself.

    remove directory dirName


回答2:

You put all this in a function, accepting a string (which is the top path to be removed.) Then check dit->d_type for DT_DIR, and call the function recursively with the new path (old path plus the name).



回答3:

I suggest working in three passes: a first (recursive) pass determine which files should be removed and remember their directories, and a second pass actually delete the files (with unlink or remove), the last pass delete the empty directories (with rmdir or remove)

The nftw function could be useful to you.

And there is always the possibility that some other process fill the directory you are removing.

Using readdir on a changing directory (i.e. on a directory in which you are removing files) could be error-prone.