Problem mit dem Löschen von Ordnern
-
Hallo,
ich hoffe nach unzähligen Stunden des Rumprobierens hoffentlich den erlösenden Tipp zu bekommen.
Also in dem Programm gibt es eine DirectoryListBox. In dieser Listbox soll über ein PopupMenu, der ausgewählte Ordner gelöscht werden können.
Hier mal die Funktion:
void __fastcall TForm1::Ordnerlschen1Click(TObject *Sender) { int button; //Abfrage button = Application->MessageBox("Ordner wirklich löschen?", "Meldung", MB_OKCANCEL + MB_DEFBUTTON1); if(button == IDOK) { TList*Liste = new TList; pFiledata Datei = new tFiledata; TSearchRec sr; String Directory; char *dateiname; int i=0,j; int index, end; AnsiString ordner; ordner = DirectoryListBox2->Directory; index = ordner.LastDelimiter("\\"); end = ordner.Length()-index+1; ordner = ordner.SubString(index+1,end); //Liste der zu löschenden Dateien erstellen int result = FindFirst("*.*", faReadOnly|faHidden|faDirectory, sr ); while(result==0) { pFiledata Item = new tFiledata; Item->Name = sr.Name; Item->Data = sr; Liste->Add(Item); i++; result=FindNext(sr); } sr.~TSearchRec(); //Dateien löschen for(j=0; j<i;j++) { Datei = (pFiledata)Liste->Items[j]; dateiname = Datei->Name.c_str(); remove(dateiname); } delete Datei; delete Liste; chdir(".."); //Ordner löschen if(!RemoveDir(ordner)) ShowMessage("Fehler beim Löschen des Verzeichnisses: " + DirectoryListBox2->Directory); DirectoryListBox2->Update(); } }
Habe es auch schon so versucht:
//Ordner löschen if(!RemoveDir(DirectoryListBox2->Directory)) ShowMessage("Fehler beim Löschen des Verzeichnisses: " + DirectoryListBox2->Directory);
Die Dateien werden einwandfrei gelöscht, aber der Ordner nie.
Was mache ich falsch?
Danke im voraus.
Edit:
Korrekte Code-Tags und Einrückungen eingefügt.
-
Geh deinen Code mal durch und schreib dir hinter jede Zeile, was du glaubst, dass sie jeweils macht. Und dann kontrolliere zur Laufzeit mittels schrittweisem Debuggen, ob deine Erwartungen erfüllt werden.
Zur vergleichenden Analyse solltest du dir ausserdem mal den FAQ-Beitrag zum Auflisten aller Dateien in Verzeichnissen ansehen und dort insbesondere auf die Rekursion, also das "Eintauchen" in Unterverzeichnisse, achten.
-
In der FileListBox kannst du einstellen, ob die versteckten Dateien auch angezeigt werden sollen, dann solltest du noch . als Filter eingeben und und und, dann sollte folgendes funktionieren:
for (int i=0;i<FileListBox1->Items->Count;i++) DeleteFile(DirectoryListBox1->Directory+"\\"+FileListBox1->Items->Strings[0]); if (!RemoveDirectory(DirectoryListBox1->Directory)) Application->MessageBox("Verzeichnis konnte nicht gelöscht werden.","Fehler",16);
-
Erstmal Danke für eure Antworten.
@Jansen:
Hab es mir nochmal durchgelesen und ich hatte die höheren Verzeichnisse garnicht berücksichtigt.Jetzt sieht es so aus:
/--------------------------------------------------------------------------- void __fastcall GetFileList(TList*Liste,String StartDirectory) { TSearchRec sr; String Directory; int result = FindFirst((StartDirectory + "*.*").c_str(), faReadOnly|faHidden|faDirectory, sr ); while(result == 0) { Application->ProcessMessages(); if((sr.Attr & faDirectory)) // ist ein Verzeichnis { if (sr.Name[1] != '.') // Verzeichnisname ist nicht '.' oder '..', steht { // also nicht für die höheren Verzeichnisebenen Directory = StartDirectory + "\\"; GetFileList(Liste, Directory); } } else // ist normale Datei { pFiledata Item = new tFiledata; Item->Name = sr.Name; Item->Path = StartDirectory; Item->Data = sr; Liste->Add(Item); } result=FindNext(sr); } sr.~TSearchRec(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Ordnerlschen1Click(TObject *Sender) { int button; int index, end; AnsiString ord, loeordner; //Abfrage button = Application->MessageBox("Ordner wirklich löschen?", "Meldung", MB_OKCANCEL + MB_DEFBUTTON1); if(button == IDOK) { ord = DirectoryListBox2->Directory; index = ord.LastDelimiter("\\"); end = ord.Length()-index+1; loeordner = ord.SubString(index+1,end); TList*FileList = new TList; GetFileList(FileList, ord); pFiledata Item; for(int i = 0; i < FileList->Count; i++) { Application->ProcessMessages(); Item = (pFiledata)FileList->Items[i]; remove(Item->Name.c_str()); delete Item; } delete FileList; chdir(".."); //ShowMessage(GetCurrentDir()); //Ordner löschen if(!RemoveDir(loeordner)) ShowMessage("Fehler beim Löschen des Verzeichnisses: " + DirectoryListBox2->Directory); } DirectoryListBox2->Update(); } //---------------------------------------------------------------------------
Wenn ich folgende Zeile aus dem FAQ
Directory = StartDirectory + (AnsiString)sr.Name + "\\";
so übernehme löscht er mir den Ordner (wenn das Verzeichnis leer ist), löscht aber nicht die enthaltenen Dateien(wenn vorhanden), da ich ja den zu löschenden Ordner komplett übergebe.
Ich steh grad echt wie der Ochs vorm Berg.
@Windoof:
Ich will ja nicht einzelne Dateien löschen, die über eine FileListBox ausgewählt werden, sondern einen Ordner mit enthaltenen Dateien, der im DirectoryFileList gewählt wird.
-
Weis denn keiner Rat?
-
Nichts ersetzt ein ausführliches debugging. Hast du den zweiten Teil von Jansens antwort s chon ausgeführt? mit dem Debugger durch den Code zu steppen? Betrachte dabei auch immer die Variableninhalte, etc.
-junix
btw: der Link da ist nicht zum Spass sondern, zum durchlesen da (o;
-
Gut ich habe nochmals diese zwei Funktionen schritt für schritt gedebuggt:
Mir ist diesmal etwas aufgefallen, das ich vorher nicht bemerkt hatte.
Ich habe zwei Zeilen geändert:
1.Directory = StartDirectory + (AnsiString)sr.Name + "\\";
GetFileList(FileList, ord + "\\");
Soweit so gut. Sehe auch ein warum das ein Fehler war. Es wurde vorher erst der aktuelle Ordner in die Liste aufgenommen, dann erst rekursiv dessen Inhalt.
Das Problem, dass ich den leeren Ordner dennoch nicht löschen kann bleibt vorhanden. Daraufhin habe ich diese zwei Funktionen weiter gedebuggt, aber keinen Anhaltspunkt gefunden.
Vielleicht wäre ein Tipp ala "Schau mal in dem Teil hast du Misst gebaut" hilfreich.
p.s.: Natürlich lese ich Links die mir gepostet werden, die ja auch der Lösung meines Problems dienen sollen. Doch man sollte auch sehen, dass man manchmal irgendwie auf der Leitung steht. Und ich kann euch versichern, dass ich es mir hier nicht einfach gemacht habe und gleich einen Beitrag gestartet habe. Gewiss nicht!
Gruß Meik
-
ich habs letztendlich hinbekommen. vielen dank nochmal an alle.