puedo - ¿Cómo eliminar una carpeta en C++?
manipular archivos y directorios en c# (14)
//Para ventanas:
#include <direct.h>
if(_rmdir("FILEPATHHERE") != -1)
{
//success
} else {
//failure
}
¿Cómo puedo eliminar una carpeta usando C ++?
Si no existe una plataforma multiplataforma, ¿cómo hacerlo para los sistemas operativos más populares: Windows, Linux, Mac, iOS, Android? ¿Funcionaría una solución POSIX para todos?
Con C ++ 17 puede usar std::filesystem
, en C ++ 14 std::experimental::filesystem
ya está disponible. Ambos permiten el uso del filesystem::remove()
de filesystem::remove()
.
C ++ 17:
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);
}
C ++ 14:
#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.
Nota 1: Esas funciones arrojan filesystem::remove() en caso de errores. Si desea evitar excepciones, utilice las variantes sobrecargadas con std::error_code
como segundo parámetro. P.ej
#include <experimental/filesystem>
std::experimental::filesystem::path::remove("myDirectory");
Nota 2: La conversión a std::filesystem::path
ocurre implícitamente a partir de diferentes codificaciones, por lo que puede pasar cadenas a filesystem::remove()
.
El directorio debe estar vacío y su programa debe tener permisos para eliminarlo
pero la función llamada rmdir lo hará
rmdir("C:/Documents and Settings/user/Desktop/itsme")
El directorio debe estar vacío.
BOOL RemoveDirectory( LPCTSTR lpPathName );
El estándar de C ++ define la función remove (), que puede o no eliminar una carpeta, dependiendo de la implementación. Si no es así, debe utilizar una función específica de implementación, como rmdir ().
Eliminar carpeta (subcarpetas y archivos) en Windows (VisualC ++) que no utiliza las API de Shell, esta es la mejor muestra de trabajo:
#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;
}
Fuente: http://www.codeguru.com/forum/showthread.php?t=239271
Intente usar el sistema " rmdir -s -q file_to_delte
".
Esto eliminará la carpeta y todos los archivos en ella.
Mi propia implementación basada en hB0 que también te permite ver la cantidad de archivos en cada carpeta también con un pequeño aumento de rendimiento.
#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;
}
Para Linux (he corregido errores en el código de arriba):
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);
}
Para ventanas:
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);
}
}
Recomiendo encarecidamente utilizar Boost.FileSystem.
http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm
En tu caso, eso sería
Si está usando Windows, mire este enlace . De lo contrario, puede buscar su api de versión específica del sistema operativo. No creo que C ++ tenga una forma de plataforma cruzada para hacerlo. Al final, NO es el trabajo de C ++, es el trabajo del sistema operativo.
También puedes probar esto si estás en Linux:
system("rm -r path");
Utilice SHFileOperation para eliminar la carpeta de forma recursiva
std::error_code errorCode;
if (!std::filesystem::path::remove("myEmptyDirectoryOrFile", errorCode)) {
std::cout << errorCode.message() << std::endl;
}