PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Nach Dateien auf der Festplatte suchen!


Ganon
2003-02-25, 13:45:37
Hi,

wie kann ich mit dem Borland C++ Builder Standard nach Dateien suchen? Ich bräuchte ein Programm welches nach bestimmten Dateien auf allen Laufwerken sucht und sie dann löscht! Sollte die Datei einen Schreibschutz haben dann sollte der entfernt werden um die Datei zu löschen!
Wie stelle ich sowas an?

Danke!

Xmas
2003-02-25, 13:52:27
Suche nach Dateien auf einem Laufwerk mit BCB:
http://www.forum-3dcenter.net/vbulletin/showthread.php?s=&threadid=50218

Ganon
2003-02-25, 15:48:46
Hi,

ich habe ein Problem mit den Laufwerken! Ich bekomme nur ASCII-Code zurückgegeben! Wie kann ich die Umwandeln, damit ich einen Buchstaben habe?

Danke!

Ganon
2003-02-25, 16:32:44
Hi,

also um es nochmal genau zu sagen:

Ich bekomme statt "c", "99" zurückgegeben! Wie wandle ich das jetzt um?

stabilo_boss13
2003-02-25, 17:06:05
Originally posted by Ganon
Hi,

also um es nochmal genau zu sagen:

Ich bekomme statt "c", "99" zurückgegeben! Wie wandle ich das jetzt um? Kannst du mal deine Funktion posten? Die Beispielfunktion von Xmas hat keinen Rückgabewert. Die füllt ja nur ein Memo.

Xmas
2003-02-25, 17:27:07
Originally posted by Ganon
Hi,

also um es nochmal genau zu sagen:

Ich bekomme statt "c", "99" zurückgegeben! Wie wandle ich das jetzt um?
Mit einem (char)-Cast?
Wie ermittelst du denn die Laufwerksbuchstaben, dass sie nicht von vornherein als char vorliegen?

Ganon
2003-02-25, 17:39:03
Ich hab den Code jetzt leider nicht hier (bin Zuhause)! Aber er ist aus der Hilfe von Borland rauskopiert! Das Beispiel ist eigendlich für Konsolenanwendung und dort wurde mit printf und "%c" der ASCII-Code in einen Buchstaben gewandelt!

Ich glaube der Befehl heiß getdrive oder so! Ich habe in der Suchfunktion "Laufwerksbuchste" eingegeben und dann war es das 2. von oben (Version 6 Personal)!

Der Ablauf war so:

Mit einer "for" Schleife zählt er von 0 bis 26! Dann nimmt er diesen Wert +'a' (bzw. 97 in ASCII) und dann versucht er mit setDrive (oder so) auf dieses Laufwerk zu wechseln! Gelingt es wandelt er dann die Zahl in einen Buchstaben!

Geht es denn noch eleganter?

Ich dachte mir das ich einfach das Zeug von XMas da nehme und das in eine Schleife packe (also SucheMp3s(<Laufwerk>) und <Laufwerk> halt mit der oben genannten Methode ändere!

Auf jeden Fall soll die Routine für jedes Laufwerk ausgeführt werden!

Unregistered
2003-02-25, 17:48:16
Er meint wohl getDisk und setDisk! Ich hab den Code mal hier!


/* Druckt die verfügbaren Laufwerksbuchstaben */
printf("Available drives:\n");
for (disk = 0;disk < 26;++disk)
{
setdisk(disk);
if (disk == getdisk())

printf("%c: drive is available\n", disk + 'a');
}

Xmas
2003-02-25, 18:04:45
Na dann sollte doch folgendes gehen (für MP3-Suche, um andere Dateien zu finden muss SucheMP3s natürlich geändert werden):

char drive[] = " :";
for (disk = 0;disk < 26;++disk)
{
setdisk(disk);
if (disk == getdisk())
{
drive[0] = disk + 'a';
SucheMP3s(AnsiString(drive, 2));
}
}

Ganon
2003-02-25, 18:16:17
Vielen Dank!:)

Ganon
2003-02-26, 12:11:22
Hi,

das Programm ist jetzt soweit fertig nur habe ich noch ein lästiges Problem!
Wie kann ich die ganze Sucherei abbrechen?

Das Formular ist beim Suchen fest! Fast so wie ein Absturz, d.h. andere Fenster "übermalen" das Formular, es werden auch keine Befehle entgegengenommen, während des Suchens!

Wie kann ich das ändern? Bei mehreren Laufwerken bzw. Netzlaufwerken kann das nämlich sehr lange dauern!

Eine Abbruchfunktion wäre nicht schlecht!

P.S.: Was macht dieser Abschnitt?

if( 0 == FindFirst( Path + "\\*", faDirectory, SRec ) )
{
do
{
if( (SRec.Name != ".") && (SRec.Name != "..") ) SucheMP3s( Path + "\\" + SRec.Name );
}
while( 0 == FindNext( SRec ) );
FindClose( SRec );
}

Xmas
2003-02-26, 12:45:25
Originally posted by Ganon
P.S.: Was macht dieser Abschnitt?

if( 0 == FindFirst( Path + "\\*", faDirectory, SRec ) )
{
do
{
if( (SRec.Name != ".") && (SRec.Name != "..") ) SucheMP3s( Path + "\\" + SRec.Name );
}
while( 0 == FindNext( SRec ) );
FindClose( SRec );
}
Er sucht alle Unterverzeichnisse und ruft für jedes (außer '.' und '..') rekursiv die Suchfunktion auf.

Xmas
2003-02-26, 13:02:28
Was das Abbrechen angeht, solltest du dich mal mit Multithreading befassen. Die VCL bietet dafür die Klasse TThread, die du ableiten musst und die Methode Execute() überschreiben. In dieser Methode überprüfst du permanent das Terminated-Flag und machst die Suche.

Und in der Click-Methode des Abbrechen-Buttons rufst du dann SuchthreadInstanz.Terminate() auf, wodurch das Terminated-Flag gesetzt wird.

Ganon
2003-02-26, 13:20:16
Hi,

boah! Überlaste mich bitte nicht! Ich bin in C++ noch Anfänger!

Könntest du mir vielleicht mal ein kleines Beispiel dafür geben? In der Hilfe steht wieder soviel das man am Ende nix weiß!

Danke!

Xmas
2003-02-26, 14:03:58
Mit Datei->Neu->Anderes...->Thread Objekt erstellst du eine neue von TThread abgeleitete Klasse. Da gibtst du dann einen Klassennamen an, z.B. TMySearchThread.

In die automatisch erstellte Methode TMySearchThread::Execute() fügst du jetzt deinen Suchcode ein, der so aussehen muss dass er regelmäßig das Flag Terminated abfragt. Falls Terminated gesetzt ist, sollte ein return kommen.

In deine Formularklasse (üblicherweise TForm1) fügst du dann einen Member TMySearchThread * Thread ein, der im Konstruktor auf NULL gesetzt werden sollte, sowie eine Methode OnThreadTerminate, definiert wie unten beschrieben.

Außerdem zwei Buttons, einer zum Starten und einer zum Abbrechen (Enabled = false).


__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Thread = NULL;
}

void __fastcall TForm1::OnThreadTerminate(TObject * Sender)
{
delete Thread;
Thread = NULL;
Form1->Button1->Enabled = true;
Form1->Button2->Enabled = false;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form1->Button2->Enabled = true;
Form1->Button1->Enabled = false;
Thread = new TMySearchThread(true);
Thread->OnTerminate = OnThreadTerminate;
Thread->Resume();
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (Thread)
Thread->Terminate();
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete Thread;
Thread = NULL;
}

Ganon
2003-02-26, 17:10:49
*ocl**ocl**ocl**ocl**ocl*
Ich kann das einfach nicht! Naja, egal! Kann man halt nicht abbrechen, solange ich Multithreading nicht kann!

Trotzdem danke!

Ganon
2003-03-05, 17:54:30
Hi, da bin ich wieder!

Ich habe ein neues "Problem"!

Erstmal erklären was ich schon alles gemacht habe!

Also auf einem Schalter sucht er! Dann kopiert er die gefundenen Pfade in einen DynamischenArray und wenn er fertig ist zeigt er die Pfade in einem Memo an! Dann kann man auf einen anderen Schlater klicken um diese zu löschen!

Nun möchte ich aber das der Anwender auswählen kann welche dieser Dateien gelöscht werden sollen!
Nur habe ich keinen Schimmer wie ich das grafisch anstellen kann (am besten mit dieses "Häkchenfeldern")!
Braucht man dazu schon ne "echte" Datenbank? Ich denke mal nicht, oder?

Kann mir jemand helfen?

Danke!

stabilo_boss13
2003-03-05, 18:16:24
Originally posted by Ganon
Dann kopiert er die gefundenen Pfade in einen DynamischenArray und wenn er fertig ist zeigt er die Pfade in einem Memo an! Dann kann man auf einen anderen Schlater klicken um diese zu löschen!

Nun möchte ich aber das der Anwender auswählen kann welche dieser Dateien gelöscht werden sollen!
Nur habe ich keinen Schimmer wie ich das grafisch anstellen kann (am besten mit dieses "Häkchenfeldern")!
Braucht man dazu schon ne "echte" Datenbank? Ich denke mal nicht, oder?

Kann mir jemand helfen?

Danke! Zeig doch die Pfade einfach in einer Listbox anstatt in einem Memo an. Dort kann der Anwender dann mit SHIFT+Click oder STRG+Click auswählen (wie im Explorer). Vielleicht kannst du dir dann sogar das dynamische Array sparen, wenn du gleich die Listbox füllst.