RemoveDirectory(); Elimina solo el directorio vacío, pero ¿cómo eliminar los directorios que tienen archivos dentro?¿Cómo eliminar el directorio recursivamente?
Respuesta
Si está preparado para usar la API de Windows, la manera más fácil de hacerlo es llamar al SHFileOperation
. Use la operación FO_DELETE
y no olvide doblemente el nombre del directorio.
Tenga en cuenta que SHFileOperation funciona muy bien para las aplicaciones del Modo de usuario, pero no funciona cuando se llama desde un Servicio de Windows, especialmente si se utiliza Suplantación para eliminar un directorio en un recurso compartido de red UNC. Para este escenario necesitarás hacer el trabajo pesado y usar FindFirstFile()/FindNext() con DeleteFile()/RemoveDirectory() de la manera difícil – WebDrive
Normalmente, si no hay un método de biblioteca disponible, esto se realiza por recursión. Una función itera todas las entradas de directorio, borrando archivos 'ordinarios' y llamándose a sí mismo con cualquier ruta de directorio encontrada. Esto destruye árboles de directorios completos (mi versión de Windows tiene comprobaciones explícitas de la ruta pasada para evitar que destruya las carpetas del sistema operativo en caso de pasar accidentalmente un parámetro suicida).
Esto puede ser escaso, pero considerar el uso de
system("rd /s /q ...");
Es feo, pero es demasiado simple como para ignorarlo. También tiene todos los elementos "cómo lidiar con los archivos en las redes compartidas". Cualquier solución que se te ocurra es probablemente una (incompleta y/o incorrecta) reimplementación de rd
, por lo que llamar al proceso externo sería una buena reutilización del código. ;-)
Reutilización y anulación del código sin siquiera un error de compilación si rd no existe . Para un programa muy pequeño, esto podría ser útil y correcto, para los de larga duración, menos. Personalmente, siempre verificaría si ese comando realmente existe. –
@phresnel: la pregunta es solo para sistemas Windows y 'rd' está disponible en todos los sistemas Windows de manera predeterminada. Me arriesgaría y afirmaría que 'rd' está disponible es más probable que 'SHFileOperation' esté disponible ('SHFileOperation' solo ha existido desde Windows XP, y ha quedado en desuso con Windows Vista). –
La probabilidad es menos relevante para mí. Personalmente, quiero un error de tiempo de compilación si alguna funcionalidad no está allí; con el sistema nunca tendrá errores de compilación. Como se dijo, para programas pequeños, específicos del sistema, esto podría estar bien. Pero recomendaría que no se aplique a programas de mayor duración o duración. Nunca se sabe lo que hay en 5, 10 o 15 años a partir de ahora. Si de pronto todos hubieran cambiado a Mac o Linux, seguramente también querrían que su dinero en efectivo se ejecutara en esa plataforma. –
La mejor solución, si puede usarla, es boost::filesystem::remove_all
. De esta forma, no tiene que preocuparse por las cosas específicas de la plataforma. No conozco ninguna otra solución independiente de plataforma; la forma usual de lo contrario implicaría leer el directorio y descender recursivamente (pero la forma de leer el directorio también usa boost::filesystem
o el código dependiente del sistema).
Según MSDN, SHFileOperation no es seguro para subprocesos cuando se utiliza con rutas de acceso relativas. Solo se puede usar de forma segura con rutas absolutas.
recomiendo el uso de este código en su lugar:
double directory_delete(char *pathname)
{
string str(pathname);
if (!str.empty())
{
while (*str.rbegin() == '\\' || *str.rbegin() == '/')
{
str.erase(str.size()-1);
}
}
replace(str.begin(),str.end(),'/','\\');
struct stat sb;
if (stat((char *)str.c_str(),&sb) == 0 &&
S_ISDIR(sb.st_mode))
{
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
TCHAR DirPath[MAX_PATH];
TCHAR FileName[MAX_PATH];
_tcscpy(DirPath,(char *)str.c_str());
_tcscat(DirPath,"\\*");
_tcscpy(FileName,(char *)str.c_str());
_tcscat(FileName,"\\");
hFind = FindFirstFile(DirPath,&FindFileData);
if (hFind == INVALID_HANDLE_VALUE) return 0;
_tcscpy(DirPath,FileName);
bool bSearch = true;
while (bSearch)
{
if (FindNextFile(hFind,&FindFileData))
{
if (!(_tcscmp(FindFileData.cFileName,".") &&
_tcscmp(FindFileData.cFileName,".."))) continue;
_tcscat(FileName,FindFileData.cFileName);
if ((FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY))
{
if (!directory_delete(FileName))
{
FindClose(hFind);
return 0;
}
RemoveDirectory(FileName);
_tcscpy(FileName,DirPath);
}
else
{
if (FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_READONLY)
_chmod(FileName, _S_IWRITE);
if (!DeleteFile(FileName))
{
FindClose(hFind);
return 0;
}
_tcscpy(FileName,DirPath);
}
}
else
{
if (GetLastError() == ERROR_NO_MORE_FILES)
bSearch = false;
else
{
FindClose(hFind);
return 0;
}
}
}
FindClose(hFind);
return (double)(RemoveDirectory((char *)str.c_str()) == true);
}
else
{
return 0;
}
}
Si desea utilizar mi código "tal cual", tendrá que estas cabeceras y tal en la parte superior de su archivo CPP:
#include <windows.h> // winapi
#include <sys/stat.h> // stat
#include <tchar.h> // _tcscpy,_tcscat,_tcscmp
#include <string> // string
#include <algorithm> // replace
using namespace std;
... y creo que eso es todo.
Mi código se basa en este artículo:
os recomiendo no usar nunca SHFileOperation, aparte de los problemas de seguridad, que fue sustituido por IFileOperation desde Windows Vista.
Espero que esto ayude!
- 1. Cómo eliminar archivos recursivamente
- 2. Eliminar propiedades recursivamente
- 3. Obtener recursivamente el tamaño de un directorio
- 4. ¿Cómo crear recursivamente un directorio en Qt?
- 5. Cómo mostrar el contenido del directorio del FTP remoto, recursivamente
- 6. Encontrar el archivo más antiguo (recursivamente) en un directorio
- 7. Script para borrar recursivamente el directorio CVS en el servidor
- 8. Git eliminar el directorio
- 9. Eliminar el directorio VSMacros80
- 10. Ruby: ¿cómo puedo encontrar y eliminar directorios vacíos recursivamente?
- 11. Verificar recursivamente las actualizaciones del directorio git
- 12. ¿Cómo puedo copiar recursivamente los contenidos del directorio usando Perl?
- 13. Eliminar recursivamente archivos de 0 KB mediante Windows cmd
- 14. PHP - ¿Cómo eliminar las entradas vacías de una matriz recursivamente?
- 15. Subversion: cómo eliminar todos los archivos .svn recursivamente?
- 16. Comando para eliminar recursivamente todos los directorios .svn en Windows
- 17. Eliminar el atributo readonly del directorio
- 18. python: eliminar el directorio no vacío
- 19. hg ¿eliminar el directorio del repositorio?
- 20. Android Eclipse DDMS - ¿Cómo eliminar el directorio en el dispositivo?
- 21. FTP Eliminar el directorio no vacío
- 22. Difiere un directorio recursivamente, Ignorando todos los archivos binarios:
- 23. ¿Cómo puedo encontrar todos los archivos * .js en el directorio recursivamente en Linux?
- 24. Cómo cambiar el permiso de un directorio recursivamente utilizando NSFileManager setAttributes
- 25. NSFileManager eliminar contenido del directorio
- 26. No se pueden eliminar archivos recursivamente de Git
- 27. Búsqueda de archivos recursivamente
- 28. CMD: ¿Cómo puedo eliminar recursivamente el atributo "Oculto" de archivos y directorios
- 29. Objetivo c: Cómo eliminar solo todos los archivos de un directorio pero conservar el directorio
- 30. Cómo eliminar el enlace 'Directorio principal' de la carpeta raíz en la lista del directorio Apache
¿Sobre qué plataforma? –
@OliCharlesworth señor, en Windows XP –
¿Qué has intentado? – Nawaz