代码之家  ›  专栏  ›  技术社区  ›  Frank

如何删除C++中的非空目录?

  •  4
  • Frank  · 技术社区  · 14 年前

    在C++中,如何删除包含所有文件的目录?我知道有 rmdir

    我知道使用Boost文件系统应该不难,但我有点想避免仅仅为了这个小任务而构建和依赖它。。。

    4 回复  |  直到 14 年前
        1
  •  8
  •   Jerry Coffin    6 年前

    是的,通常您必须先删除内容。如果您不想使用Boost来实现这一点,那么您将不得不编写不可移植的代码来查找所有文件(例如。, FindFirstFile , FindNextFile 在窗户上, opendir readdir 在Unix和类似系统上),并将其全部删除。

    在Windows上,您还可以使用 ShFileOperation IFileOperation interface . 它们可以在内部处理递归删除,因此您只需给它指定要删除的目录的名称,其余的由它处理。

    IFileOperation 界面似乎专门设计为尽可能笨拙(例如。, IFileOperation::DeleteItem IFileOperation::PerformOperations 执行实际的删除操作。

        2
  •  5
  •   bta    14 年前

    可以使用以下代码删除非空目录。这使用Unix风格的命令,但可以使用Cygwin为Windows编译(如果您不介意使用Cygwin DLL的话)。

    void delete_folder_tree (const char* directory_name) {
        DIR*            dp;
        struct dirent*  ep;
        char            p_buf[512] = {0};
    
        dp = opendir(directory_name);
    
        while ((ep = readdir(dp)) != NULL) {
            sprintf(p_buf, "%s/%s", directory_name, ep->d_name);
            if (path_is_directory(p_buf))
                delete_folder_tree(p_buf);
            else
                unlink(p_buf);
        }
    
        closedir(dp);
        rmdir(directory_name);
    }
    
    int path_is_directory (const char* path) {
        struct stat s_buf;
    
        if (stat(path, &s_buf))
            return 0;
    
        return S_ISDIR(s_buf.st_mode);
    }
    
        3
  •  1
  •   James Curran    14 年前

    但是,在大多数情况下,是a)删除文件,然后b)删除目录。(任何通往这一点的捷径都肯定依赖于操作系统,而且通常依赖于操作系统版本)

        4
  •  1
  •   ChrisF    14 年前

    您需要遍历目录中的所有文件,并首先删除这些文件。尽管如此,代码还是依赖于平台的(正如其他人所提到的)。

    MSDN page (从中提取,因此将有未定义的变量)将适用于Windows,但不适用于Unix/Linux:

    HANDLE hFind = FindFirstFile(szDir, &ffd);
    
    if (INVALID_HANDLE_VALUE == hFind) 
    {
        DisplayErrorBox(TEXT("FindFirstFile"));
        return dwError;
    } 
    
    // List all the files in the directory with some info about them.
    do
    {
        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            _tprintf(TEXT("  %s   <DIR>\n"), ffd.cFileName);
        }
        else
        {
            filesize.LowPart = ffd.nFileSizeLow;
            filesize.HighPart = ffd.nFileSizeHigh;
            _tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
        }
    }
    while (FindNextFile(hFind, &ffd) != 0);
    
    dwError = GetLastError();
    if (dwError != ERROR_NO_MORE_FILES) 
    {
        DisplayErrorBox(TEXT("FindFirstFile"));
    }
    
    FindClose(hFind);
    

    打印文件信息,但将其修改为删除应该不会太难。

    您需要为树中的所有子目录递归调用此函数。