web-dev-qa-db-ja.com

C ++でフォルダーを削除する方法は?

C++を使用してフォルダーを削除するにはどうすればよいですか?

クロスプラットフォームの方法が存在しない場合、最も人気のあるOS(Windows、Linux、Mac、iOS、Android)に対してそれを行う方法は? POSIXソリューションはそれらすべてに対して機能しますか?

38
user88240

Boost.FileSystemを使用することを強くお勧めします。

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

あなたの場合、それは

boost :: filesystem :: remove_all(yourPath)

59
Edouard A.

シェルAPIを使用していないWindows(VisualC++)のフォルダー(sub_foldersとfiles)を削除します。これは最適なサンプルです:

#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

21
hB0

C++ 17では、 _std::filesystem_ を使用できます。C++ 14では _std::experimental::filesystem_ はすでに使用可能です。どちらも filesystem::remove() の使用を許可します。

C++ 17:

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

C++ 14:

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

注1:これらの関数は、エラーの場合に filesystem_error をスローします。例外のキャッチを避けたい場合は、2番目のパラメーターとして _std::error_code_ でオーバーロードされたバリアントを使用します。例えば。

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

注2: _std::filesystem::path_ への変換は、異なるエンコーディングから暗黙的に行われるため、文字列を filesystem::remove() に渡すことができます。

17
Roi Danton

ディレクトリは空でなければなりません。

BOOL RemoveDirectory( LPCTSTR lpPathName );
9
Vinay
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);
}
7
user4385463

SHFileOperationを使用して、フォルダーを再帰的に削除します

5
user1803888

ディレクトリは空である必要があり、プログラムには削除する権限が必要です

しかし、rmdirと呼ばれる関数がそれを行います

rmdir("C:/Documents and Settings/user/Desktop/itsme") 
4
TStamper

Linuxを使用している場合は、これを試すこともできます。

system("rm -r path");
3
Meysam

システム「rmdir -s -q file_to_delte "。
これにより、フォルダーとその中のすべてのファイルが削除されます。

0
xlu

C++標準では、remove()関数が定義されています。これは、実装に応じて、フォルダーを削除する場合としない場合があります。必要ない場合は、rmdir()などの実装固有の関数を使用する必要があります。

0
anon

HB0に基づいた独自の実装により、各フォルダー内のファイル数を表示することもできますが、パフォーマンスは少し向上します。

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <windows.h>
#include <conio.h>

union seperated {
  struct {
    unsigned int low;
    unsigned int high;
  } uint;
  unsigned long long ull;
};

unsigned long long num_dirs  = 1;
unsigned long long num_files = 0;
seperated size_files;

int DeleteDirectory( char* refRootDirectory );      //predeclare it

int DeleteDirectory( char* refRootDirectory ) {
    HANDLE      hFile;              // Handle to directory
    std::string strFilePath;            // Filepath
    WIN32_FIND_DATA FileInformation;    // File information
    int     dwError;            // Folder deleting error
    std::string strPattern;         // Pattern

    strPattern = (std::string)(refRootDirectory) + "\\*.*";
    hFile = ::FindFirstFile( strPattern.c_str(), &FileInformation );

    if( hFile != INVALID_HANDLE_VALUE )
    {
        do {
            if( FileInformation.cFileName[0] != '.' ) {
                strFilePath.erase();
                strFilePath = std::string(refRootDirectory) + "\\" + FileInformation.cFileName;

                if( FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
                    DeleteDirectory( (char*)strFilePath.c_str() );

                    dwError = ::GetLastError();
                    if( dwError != ERROR_NO_MORE_FILES ) {
                        std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
                        return dwError;
                    } else {
                        // Set directory attributes
                        if( ! ::SetFileAttributes(refRootDirectory,FILE_ATTRIBUTE_NORMAL) ) {
                            std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
                            return ::GetLastError();
                        }

                        // Delete directory
                        if( ! ::RemoveDirectory(refRootDirectory) ) {
                            std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
                            return ::GetLastError();
                        }
                    }

                    ++num_dirs;
                } else {

                    // Set file attributes
                    if( ! ::SetFileAttributes(strFilePath.c_str(),FILE_ATTRIBUTE_NORMAL) ) {
                        std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
                        return ::GetLastError();
                    }

                    // Delete file
                    if ( ! ::DeleteFile(strFilePath.c_str()) ) {
                        std::cout << "!ERROR!: [[" << strFilePath.c_str() << "]]\n";
                        return ::GetLastError();
                    }

                    size_files.ull       += FileInformation.nFileSizeLow;
                    size_files.uint.high += FileInformation.nFileSizeHigh;

                    ++num_files;
                }
            }
        } while( ::FindNextFile(hFile,&FileInformation) );

        // Close handle
        ::FindClose( hFile  );
    }

    return 0;
}

unsigned long long num_files_total=0;
unsigned long long num_dirs_total=0;
unsigned long long total_size_files=0;

void my_del_directory( char* dir_name ) {
    int iRC = DeleteDirectory( dir_name );
    //int iRC=0;

    std::cout << "\"" << dir_name << "\""
             "\n    Folders: " << num_dirs
          << "\n    Files:   " << num_files
          << "\n    Size:    " << size_files.ull << " Bytes";
    if(iRC)
    {
        std::cout << "\n!ERROR!: " << iRC;
    }
    std::cout << "\n\n";

    num_dirs_total   += num_dirs;
    num_files_total  += num_files;
    total_size_files += size_files.ull;
    num_dirs  = 1;
    num_files = 0;
    size_files.ull = 0ULL;
    return;
}

int main( void )
{
    size_files.ull = 0ULL;

    my_del_directory( (char*)"C:\Windows\temp"      );
        // This will clear out the System temporary directory on windows systems

    std::cout << "\n\nResults" << "\nTotal Folders: " << num_dirs_total
                   << "\nTotal Files:   " << num_files_total
                   << "\nTotal Size:    " << total_size_files << " Bytes\n";

    return 0;
}
0
Jack Giffin

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);
}

Windowsの場合:

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);
    }
}
0

Poco ライブラリを使用している場合、ディレクトリを削除するポータブルな方法を次に示します。

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

「true」を指定してremove関数を呼び出すと、ディレクトリ内のすべてのファイルとサブディレクトリが再帰的に削除されます。

0

// Windowsの場合:

#include <direct.h>


if(_rmdir("FILEPATHHERE") != -1)
{
  //success     
} else {
  //failure
}
0
JP_