Removing a non empty directory programmatically in C or C++

后端 未结 8 2458
一生所求
一生所求 2020-11-27 16:50

How to delete a non empty directory in C or C++? Is there any function? rmdir only deletes empty directory. Please provide a way without using any external library.

8条回答
  •  离开以前
    2020-11-27 17:23

    Many unix-like systems (Linux, the BSDs, and OS X, at the very least) have the fts functions for directory traversal.

    To recursively delete a directory, perform a depth-first traversal (without following symlinks) and remove every visited file:

    int recursive_delete(const char *dir)
    {
        int ret = 0;
        FTS *ftsp = NULL;
        FTSENT *curr;
    
        // Cast needed (in C) because fts_open() takes a "char * const *", instead
        // of a "const char * const *", which is only allowed in C++. fts_open()
        // does not modify the argument.
        char *files[] = { (char *) dir, NULL };
    
        // FTS_NOCHDIR  - Avoid changing cwd, which could cause unexpected behavior
        //                in multithreaded programs
        // FTS_PHYSICAL - Don't follow symlinks. Prevents deletion of files outside
        //                of the specified directory
        // FTS_XDEV     - Don't cross filesystem boundaries
        ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
        if (!ftsp) {
            fprintf(stderr, "%s: fts_open failed: %s\n", dir, strerror(curr->fts_errno));
            ret = -1;
            goto finish;
        }
    
        while ((curr = fts_read(ftsp))) {
            switch (curr->fts_info) {
            case FTS_NS:
            case FTS_DNR:
            case FTS_ERR:
                fprintf(stderr, "%s: fts_read error: %s\n",
                        curr->fts_accpath, strerror(curr->fts_errno));
                break;
    
            case FTS_DC:
            case FTS_DOT:
            case FTS_NSOK:
                // Not reached unless FTS_LOGICAL, FTS_SEEDOT, or FTS_NOSTAT were
                // passed to fts_open()
                break;
    
            case FTS_D:
                // Do nothing. Need depth-first search, so directories are deleted
                // in FTS_DP
                break;
    
            case FTS_DP:
            case FTS_F:
            case FTS_SL:
            case FTS_SLNONE:
            case FTS_DEFAULT:
                if (remove(curr->fts_accpath) < 0) {
                    fprintf(stderr, "%s: Failed to remove: %s\n",
                            curr->fts_path, strerror(curr->fts_errno));
                    ret = -1;
                }
                break;
            }
        }
    
    finish:
        if (ftsp) {
            fts_close(ftsp);
        }
    
        return ret;
    }
    

提交回复
热议问题