inline bool delete_subdirectories_recursive (const std::string &refcstrRootDirectory, const char *dont_delete_this) { DIR *d = opendir(refcstrRootDirectory.c_str()); if(!d) { return false; } struct dir_close { DIR *d_; dir_close(DIR *d) : d_(d) {} ~dir_close() { ::closedir(d_); } } dc(d); (void)dc; struct ::dirent *de; struct ::stat st; std::string fn; while((de=::readdir(d))) { if( de->d_name[0] == '.' && ( de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ) { continue; } if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0) { continue; } fn = refcstrRootDirectory; fn += '/'; fn += de->d_name; if(std::remove(fn.c_str())) { if(::stat(fn.c_str(), & st)) { return false; } if(S_ISDIR(st.st_mode)) { if(!delete_subdirectories_recursive(fn, 0) ) { return false; } } else { return false; } } } return std::remove(refcstrRootDirectory.c_str()) ? false : true; }
//This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this" inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this) { return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this ); }
inline bool delete_subdirectories_recursive (const std::string &refcstrRootDirectory, const char *dont_delete_this, unsigned int count) { bool bSubdirectory = false; // Flag, indicating whether // subdirectories have been found void * hFile; // Handle to directory std::string strFilePath; // Filepath std::string strPattern; // Pattern winapi::win32_find_data_t FileInformation; // File information //Find all files and directories strPattern = refcstrRootDirectory + "\\*.*"; hFile = winapi::find_first_file(strPattern.c_str(), &FileInformation); if(hFile != winapi::invalid_handle_value){ do{ //If it's not "." or ".." or the pointed root_level dont_delete_this erase it if(FileInformation.cFileName[0] != '.' && !(dont_delete_this && count == 0 && std::strcmp(dont_delete_this, FileInformation.cFileName) == 0)){ strFilePath.erase(); strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName; //If it's a directory, go recursive if(FileInformation.dwFileAttributes & winapi::file_attribute_directory){ // Delete subdirectory if(!delete_subdirectories_recursive(strFilePath, dont_delete_this, count+1)) return false; } //If it's a file, just delete it else{ // Set file attributes //if(::SetFileAttributes(strFilePath.c_str(), winapi::file_attribute_normal) == 0) //return winapi::get_last_error(); // Delete file winapi::delete_file(strFilePath.c_str()); } } //Go to the next file } while(winapi::find_next_file(hFile, &FileInformation) == 1); // Close handle winapi::find_close(hFile); //See if the loop has ended with an error or just because we've traversed all the files if(winapi::get_last_error() != winapi::error_no_more_files){ return false; } else { //Erase empty subdirectories or original refcstrRootDirectory if(!bSubdirectory && count) { // Set directory attributes //if(::SetFileAttributes(refcstrRootDirectory.c_str(), FILE_ATTRIBUTE_NORMAL) == 0) //return ::GetLastError(); // Delete directory if(winapi::remove_directory(refcstrRootDirectory.c_str()) == 0) return false; } } } return true; }