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

时间:2010-07-19 20:01:11

标签: c++ file file-io

在C ++中,如何删除包含所有包含文件的目录?我知道有rmdir,但它只会删除非空目录,所以如何首先列出并删除所有包含的文件?

我知道使用Boost Filesystem应该不会很难,但我有点想避免构建并依赖于它只是为了这个小任务......

4 个答案:

答案 0 :(得分:8)

是的,您通常必须先删除内容。如果您不想为此使用Boost,那么您几乎不得不编写非可移植代码来查找所有文件(例如,FindFirstFileFindNextFile在Windows上,{{1}在Unix上使用opendir和类似的)递归地删除所有这些。

在Windows上,您还可以使用ShFileOperationIFileOperation interface。这些可以在内部处理递归删除,因此您只需为其指定要删除的目录的名称,然后处理剩下的内容。

与大多数COM事物一样,readdir界面似乎是专门设计为尽可能笨拙(例如,IFileOperation实际上并没有删除任何东西 - 它只是添加一个项目到一个要删除的事项列表。然后您必须致电IFileOperation::DeleteItem进行实际删除。

答案 1 :(得分:5)

您可以使用以下代码删除非空目录。这使用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);
}

答案 2 :(得分:1)

您需要遍历目录中的所有文件并首先删除它们。代码依赖于平台(正如其他人所提到的那样)。

例如,此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);

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

您需要以递归方式对树中的所有子目录进行调用。

答案 3 :(得分:1)

首先,任何文件i / o - 特别是目录更改,都与操作系统有很大关系。

但是,在大多数情况下,它是a)删除文件,然后b)删除目录。 (任何快捷方式肯定会取决于操作系统,并且通常是操作系统版本的依赖)