2009-04-09 237 views
26

如何使用C++删除文件夹?如果不存在跨平台的方式,那么如何为最流行的操作系统 - Windows,Linux,Mac,iOS,Android?做到这一点。 POSIX解决方案是否适用于所有这些解决方案?如何删除C++中的文件夹?

回答

0

C++标准定义了remove()函数,它可能会或可能不会删除文件夹,具体取决于实现。如果不是,则需要使用特定于实现的功能,例如rmdir()。

4

的目录必须是空的,你的程序必须有权限删除它

但函数调用命令rmdir会做

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

你在Windows中使用什么头文件? – 2011-09-26 22:23:17

+0

使用_rmdir for windows,并且标题为 `#include `我相信,与_mkdir相同 – Mich 2018-01-17 01:49:43

8

的目录应该是空的。

BOOL RemoveDirectory(LPCTSTR lpPathName); 
+12

这只是我认为的Windows? Vinay拥有Apple头像,但发布了Windows特定的答案,我觉得很有趣。 ;) – Aardvark 2009-04-09 15:36:31

+9

Vinay已经没有Apple头像了) – sergtk 2012-08-31 02:20:00

+3

Vinay现在有一个Android头像:) – 2015-09-16 09:41:03

-2

如果您使用的是windows,那么看看this link。否则,你可能会寻找你的操作系统特定的版本api。我不认为C++采用跨平台的方式来实现它。最后,这不是C++的工作,而是操作系统的工作。

16

删除文件夹在Windows(VISUALC++)不使用壳牌的API(sub_folders和文件),这是最好的工作样本:

#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

+4

感谢您发布不是Boost或调用system()的东西。 – 2013-02-07 20:48:18

+0

但有一天,链接将会死亡。你打算在答案中包含相关的代码吗? – jogojapan 2013-02-26 08:56:41

+0

看起来像这个解决方案可能由于文件系统竞争而失败:DeleteFile不是原子的,这意味着删除包含它的目录可能会失败,因为该目录尚未(尚未)为空。本讲座详细解释了此问题,并提供了一种更安全的方法来删除Windows上的目录/树:https://www.youtube.com/watch?v=uhRWMGBjlO8 – 2018-03-02 19:28:55

0

//对于Windows:

#include <direct.h> 


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

使用SHFileOperation删除的文件夹recursivelly

2

你也可以试试这个,如果你是在Linux上:

system("rm -r path"); 
0

尝试利用系统 “rmdir -s -q file_to_delte” 。
这将删除文件夹及其中的所有文件。

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

我自己的基于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; 
} 
3

用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()