How can I delete a folder using C++?
If no cross-platform way exists, then how to do it for the most-popular OSes - Windows, Linux, Mac, iOS, Android? Would a POSIX solution work for all of them?
I strongly advise to use Boost.FileSystem.
http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm
In your case that would be
Delete folder (sub_folders and files) in Windows (VisualC++) not using Shell APIs, this is the best working sample:
#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;
}
Source: http://www.codeguru.com/forum/showthread.php?t=239271
With C++17 you can use std::filesystem
, in C++14 std::experimental::filesystem
is already available. Both allow the usage of 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");
Note 1:
Those functions throw filesystem_error in case of errors. If you want to avoid catching exceptions, use the overloaded variants with std::error_code
as second parameter. E.g.
std::error_code errorCode;
if (!std::filesystem::remove("myEmptyDirectoryOrFile", errorCode)) {
std::cout << errorCode.message() << std::endl;
}
Note 2:
The conversion to std::filesystem::path
happens implicit from different encodings, so you can pass strings to filesystem::remove()
.
The directory should be empty.
BOOL RemoveDirectory( LPCTSTR lpPathName );
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);
}
Use SHFileOperation to remove the folder recursivelly
The directory must be empty and your program must have permissions to delete it
but the function called rmdir will do it
rmdir("C:/Documents and Settings/user/Desktop/itsme")
You can also try this if you are on linux:
system("rm -r path");
The C++ Standard defines the remove() function, which may or may not delete a folder, depending on implementation. If it doesn't you need to use an implementation specific function such as rmdir().
//For windows:
#include <direct.h>
if(_rmdir("FILEPATHHERE") != -1)
{
//success
} else {
//failure
}
Try use system "rmdir -s -q file_to_delte
".
This will delete the folder and all files in it.
My own implementation based off hB0 that also allows you to view the number of files in each folder also with a little performance boost.
#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;
}
For linux (I have fixed bugs in code above):
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);
}
For 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);
}
}
If you are using the Poco library, here is a portable way to delete a directory.
#include "Poco/File.h"
...
...
Poco::File fooDir("/path/to/your/dir");
fooDir.remove(true);
The remove function when called with "true" means recursively delete all files and sub directories in a directory.
If you are using windows, then take a look at this link. Otherwise, you may look for your OS specific version api. I don't think C++ comes with a cross-platform way to do it. At the end, it's NOT C++'s work, it's the OS's work.
来源:https://stackoverflow.com/questions/734717/how-to-delete-a-folder-in-c