Récursive de la suppression du fichier en C sous Linux
J'ai un programme C qui, à un moment donné dans le programme a ceci:
system("rm-rf foo");
Où foo est un répertoire. J'ai décidé que plutôt que de faire appel système, il serait préférable de faire la suppression récursive droit dans le code. J'ai pris un morceau de code pour faire cela devrait être facile à trouver. Je suis bête. De toute façon, j'ai fini par écrire ceci:
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <libgen.h>
int recursiveDelete(char* dirname) {
DIR *dp;
struct dirent *ep;
char abs_filename[FILENAME_MAX];
dp = opendir (dirname);
if (dp != NULL)
{
while (ep = readdir (dp)) {
struct stat stFileInfo;
snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname, ep->d_name);
if (lstat(abs_filename, &stFileInfo) < 0)
perror ( abs_filename );
if(S_ISDIR(stFileInfo.st_mode)) {
if(strcmp(ep->d_name, ".") &&
strcmp(ep->d_name, "..")) {
printf("%s directory\n",abs_filename);
recursiveDelete(abs_filename);
}
} else {
printf("%s file\n",abs_filename);
remove(abs_filename);
}
}
(void) closedir (dp);
}
else
perror ("Couldn't open the directory");
remove(dirname);
return 0;
}
Cela semble fonctionner, mais j'ai trop peur de l'utiliser en production. Je suis sûr que j'ai fait quelque chose de mal. Personne ne sait d'une bibliothèque C pour faire de suppression récursive j'ai raté, ou quelqu'un peut souligner toutes les erreurs que j'ai fait?
Grâce.
En fait, lorsque vous passez à quelque chose de shell, il va vers le Système d'Exploitation et il fonctionne en code machine. Le noyau Unix est très optimisé, de sorte que même si vous avez codé EXACTEMENT comment il est codé dans le noyau Unix, vous auriez probablement plus que 5 à 10% d'augmentation des performances. C'est juste trop facile et commode de passer à la coque.
Voir [ Supprimer le dossier avec les éléments ](stackoverflow.com/questions/1149764/delete-folder-with-items) et la Suppression d'un répertoire non vide par programmation en C ou C++.
Intéressant: spécification POSIX pour
Voir [ Supprimer le dossier avec les éléments ](stackoverflow.com/questions/1149764/delete-folder-with-items) et la Suppression d'un répertoire non vide par programmation en C ou C++.
Intéressant: spécification POSIX pour
remove()
dit unlink()
sur la non-répertoires (fichiers, liens symboliques, etc) et rmdir()
sur les répertoires. Vous devriez vérifier que remove()
travaux - reporting et si pas. Vous devriez regarder ce qui se passe si l'argument de la fonction n'est pas un répertoire - il se plaint qu'il n'a pas pu ouvrir le répertoire (mais ne dit pas qui, et c'est mauvais aussi), puis le supprime de toute façon (ou tente de le faire).OriginalL'auteur Jim | 2010-09-30
Vous devez vous connecter pour publier un commentaire.
POSIX a une fonction appelée ftw(3) (arborescence de fichiers à pied) que
Il y a aussi la nouvelle FTW la fonction nftw avec un peu différente de l'interface.
nftw
est ce que vous êtes après que voir cette réponse à la même question.OriginalL'auteur ninjalj
bravo pour avoir peur de la mort, c'est une bonne attitude à avoir dans un cas comme celui-ci.
Je n'ai pas de bibliothèque à suggérer, dans ce cas, vous avez deux options:
1) exécuter ce code de manière exhaustive
un) et non pas sur une machine, sur le papier, avec un crayon. prenez l'arborescence des répertoires, liste de tous les éléments et exécuter le programme à chaque étape, vérifiez qu'il fonctionne
b) de compiler le code, mais remplacer l'ensemble de la suppression des appels avec une ligne qui fait un printf de vérifier qu'il fait ce qu'il doit faire
c) insérez à nouveau la suppression des appels et d'exécuter
2) utilisation de votre méthode originale (appel system())
OriginalL'auteur KevinDTimm
Je voudrais suggérer une précaution supplémentaire que vous pouvez prendre.
Presque toujours lorsque vous supprimez plusieurs fichiers et/ou répertoires, il serait une bonne idée de chroot() dans la dir avant l'exécution de tout ce qui peut détruire vos données en dehors de ce répertoire.
OriginalL'auteur Marian HackMan Marinov
Je pense que vous aurez besoin de faire appel closedir() avant recursiveDelete() (parce que vous ne voulez pas/besoin de tous les répertoires que vous entrez dans. Aussi closedir() avant d'appeler remove() parce que remove() donnera probablement une erreur sur l'open directory. Vous devriez étape à travers cette fois soigneusement pour s'assurer que readdir() n'a pas de ramassage le '..'. Méfiez-vous également de ces répertoires, vous ne souhaitez probablement pas répéter dans des répertoires qui sont
des liens physiques ou symboliques.
OriginalL'auteur Roger Nelson