Как удалить непустую директорию в C ++? - PullRequest
4 голосов
/ 20 июля 2010

В C ++, как я могу удалить каталог со всеми содержащимися в нем файлами? Я знаю, что есть rmdir, но он будет удалять только непустые каталоги, так как мне сначала перечислить и удалить все содержащиеся в нем файлы?

Я знаю, что это не должно быть сложно с помощью Boost Filesystem, но я хочу избежать сборки и зависеть от нее только для этой маленькой задачи ...

Ответы [ 4 ]

8 голосов
/ 20 июля 2010

Да, обычно вы должны сначала удалить содержимое.Если вы не хотите использовать Boost для этого, вы в значительной степени застряли в написании непереносимого кода для поиска всех файлов (например, FindFirstFile, FindNextFile в Windows, opendir, readdir вUnix и аналогичные) рекурсивно, и удалите все из них.

В Windows вы также можете использовать ShFileOperation или IFileOperation интерфейс .Они могут обрабатывать рекурсивное удаление внутри, поэтому вы просто даете ему имя каталога, который хотите удалить, и он обрабатывает все остальное.

Как и в большинстве случаев с COM, интерфейс IFileOperation, кажется, разработан специальнобыть настолько неуклюжим, насколько это возможно (например, IFileOperation::DeleteItem на самом деле ничего не удаляет - он просто добавляет элемент в список вещей, которые нужно удалить. Затем вам нужно вызвать IFileOperation::PerformOperations, чтобы выполнить фактическое удаление.

5 голосов
/ 20 июля 2010

Вы можете использовать следующий код для удаления непустого каталога. Это использует команды в стиле Unix, но может быть скомпилировано для Windows с использованием Cygwin (если вы не возражаете против зависимости от 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);
}
1 голос
/ 20 июля 2010

Прежде всего, любой файловый ввод / вывод, особенно изменение каталога, сильно зависит от ОС.

Но, по большей части, это: а) удалил файлы, затем б) удалил каталог. (любой ярлык к этому определенно зависит от ОС и часто зависит от версии ОС)

1 голос
/ 20 июля 2010

Вам нужно будет перебрать все файлы в каталоге и сначала удалить их.Однако код зависит от платформы (как уже упоминали другие).

Например, код на этой странице MSDN (из которой он извлечен, поэтому будут неопределенные переменные) будет работать для 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);

печатает информацию о файле, но адаптировать его для удаления не должно быть слишком сложно.каталоги в дереве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...