Как удалить папку в C ++? - PullRequest
       81

Как удалить папку в C ++?

36 голосов
/ 09 апреля 2009

Как я могу удалить папку с помощью C ++?

Если кроссплатформенного способа не существует, то как это сделать для самых популярных ОС - Windows, Linux, Mac, iOS, Android? Будет ли решение POSIX работать для всех из них?

Ответы [ 15 ]

58 голосов
/ 09 апреля 2009

Настоятельно советую использовать Boost.FileSystem.

http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm

В вашем случае это будет

повышение :: файловая система :: remove_all (yourPath)

20 голосов
/ 31 мая 2012

Удалить папку (вложенные папки и файлы) в Windows (VisualC ++), не используя API-интерфейсы оболочки, это лучший рабочий пример:

#include <string>
#include <iostream>

#include <windows.h>
#include <conio.h>


int DeleteDirectory(const std::string &refcstrRootDirectory,
                    bool              bDeleteSubdirectories = true)
{
  bool            bSubdirectory = false;       // Flag, indicating whether
                                               // subdirectories have been found
  HANDLE          hFile;                       // Handle to directory
  std::string     strFilePath;                 // Filepath
  std::string     strPattern;                  // Pattern
  WIN32_FIND_DATA FileInformation;             // File information


  strPattern = refcstrRootDirectory + "\\*.*";
  hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
  if(hFile != INVALID_HANDLE_VALUE)
  {
    do
    {
      if(FileInformation.cFileName[0] != '.')
      {
        strFilePath.erase();
        strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

        if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          if(bDeleteSubdirectories)
          {
            // Delete subdirectory
            int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories);
            if(iRC)
              return iRC;
          }
          else
            bSubdirectory = true;
        }
        else
        {
          // Set file attributes
          if(::SetFileAttributes(strFilePath.c_str(),
                                 FILE_ATTRIBUTE_NORMAL) == FALSE)
            return ::GetLastError();

          // Delete file
          if(::DeleteFile(strFilePath.c_str()) == FALSE)
            return ::GetLastError();
        }
      }
    } while(::FindNextFile(hFile, &FileInformation) == TRUE);

    // Close handle
    ::FindClose(hFile);

    DWORD dwError = ::GetLastError();
    if(dwError != ERROR_NO_MORE_FILES)
      return dwError;
    else
    {
      if(!bSubdirectory)
      {
        // Set directory attributes
        if(::SetFileAttributes(refcstrRootDirectory.c_str(),
                               FILE_ATTRIBUTE_NORMAL) == FALSE)
          return ::GetLastError();

        // Delete directory
        if(::RemoveDirectory(refcstrRootDirectory.c_str()) == FALSE)
          return ::GetLastError();
      }
    }
  }

  return 0;
}


int main()
{
  int         iRC                  = 0;
  std::string strDirectoryToDelete = "c:\\mydir";


  // Delete 'c:\mydir' without deleting the subdirectories
  iRC = DeleteDirectory(strDirectoryToDelete, false);
  if(iRC)
  {
    std::cout << "Error " << iRC << std::endl;
    return -1;
  }

  // Delete 'c:\mydir' and its subdirectories
  iRC = DeleteDirectory(strDirectoryToDelete);
  if(iRC)
  {
    std::cout << "Error " << iRC << std::endl;
    return -1;
  }

  // Wait for keystroke
  _getch();

  return 0;
}

Источник: http://www.codeguru.com/forum/showthread.php?t=239271

13 голосов
/ 13 апреля 2017

С C ++ 17 вы можете использовать std::filesystem, в C ++ 14 std::experimental::filesystem уже доступно. Оба позволяют использовать filesystem::remove().

C ++ 17:

#include <filesystem>
std::filesystem::path::remove("myEmptyDirectoryOrFile"); // Deletes empty directories or single files.
std::filesystem::path::remove_all("myDirectory"); // Deletes one or more files recursively.

C ++ 14:

#include <experimental/filesystem>
std::experimental::filesystem::path::remove("myDirectory");

Примечание 1: Эти функции выдают filesystem_error в случае ошибок. Если вы хотите избежать перехвата исключений, используйте перегруженные варианты с std::error_code в качестве второго параметра. Э.Г.

std::error_code errorCode;
if (!std::filesystem::path::remove("myEmptyDirectoryOrFile", errorCode)) {
    std::cout << errorCode.message() << std::endl;
}

Примечание 2: Преобразование в std::filesystem::path происходит неявно из разных кодировок, поэтому вы можете передавать строки в filesystem::remove().

9 голосов
/ 09 апреля 2009

Каталог должен быть пустым.

BOOL RemoveDirectory( LPCTSTR lpPathName );
6 голосов
/ 22 декабря 2014
void remove_dir(char *path)
{
        struct dirent *entry = NULL;
        DIR *dir = NULL;
        dir = opendir(path);
        while(entry = readdir(dir))
        {   
                DIR *sub_dir = NULL;
                FILE *file = NULL;
                char abs_path[100] = {0};
                if(*(entry->d_name) != '.')
                {   
                        sprintf(abs_path, "%s/%s", path, entry->d_name);
                        if(sub_dir = opendir(abs_path))
                        {   
                                closedir(sub_dir);
                                remove_dir(abs_path);
                        }   
                        else 
                        {   
                                if(file = fopen(abs_path, "r"))
                                {   
                                        fclose(file);
                                        remove(abs_path);
                                }   
                        }   
                }   
        }   
        remove(path);
}
5 голосов
/ 06 ноября 2012

Используйте SHFileOperation для рекурсивного удаления папки

4 голосов
/ 09 апреля 2009

Каталог должен быть пустым, и ваша программа должна иметь права на его удаление

но функция с именем rmdir сделает это

rmdir("C:/Documents and Settings/user/Desktop/itsme") 
3 голосов
/ 08 января 2013

Вы также можете попробовать это, если вы используете Linux:

system("rm -r path");
0 голосов
/ 07 июня 2019

Если вы используете библиотеку Poco , вот портативный способ удаления каталога.

#include "Poco/File.h"
...
...
Poco::File fooDir("/path/to/your/dir");
fooDir.remove(true);

Функция удаления при вызове «true» означает рекурсивное удаление всех файлов и подкаталогов в каталоге.

0 голосов
/ 08 июня 2018

Для Linux (я исправил ошибки в коде выше):

void remove_dir(char *path)
{
        struct dirent *entry = NULL;
        DIR *dir = NULL;
        dir = opendir(path);
        while(entry = readdir(dir))
        {   
                DIR *sub_dir = NULL;
                FILE *file = NULL;
                char* abs_path new char[256];
                 if ((*(entry->d_name) != '.') || ((strlen(entry->d_name) > 1) && (entry->d_name[1] != '.')))
                {   
                        sprintf(abs_path, "%s/%s", path, entry->d_name);
                        if(sub_dir = opendir(abs_path))
                        {   
                                closedir(sub_dir);
                                remove_dir(abs_path);
                        }   
                        else 
                        {   
                                if(file = fopen(abs_path, "r"))
                                {   
                                        fclose(file);
                                        remove(abs_path);
                                }   
                        }   
                }
                delete[] abs_path;   
        }   
        remove(path);
}

Для окон:

void remove_dir(const wchar_t* folder)
{
    std::wstring search_path = std::wstring(folder) + _T("/*.*");
    std::wstring s_p = std::wstring(folder) + _T("/");
    WIN32_FIND_DATA fd;
    HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                if (wcscmp(fd.cFileName, _T(".")) != 0 && wcscmp(fd.cFileName, _T("..")) != 0)
                {
                    remove_dir((wchar_t*)(s_p + fd.cFileName).c_str());
                }
            }
            else {
                DeleteFile((s_p + fd.cFileName).c_str());
            }
        } while (::FindNextFile(hFind, &fd));
        ::FindClose(hFind);
        _wrmdir(folder);
    }
}
...