| Autor |
Beitrag |
Insanctus
Hält's aus hier
Beiträge: 9
|
Verfasst: Mo 08.10.07 10:25
Ich grüße euch.
Eins Vorab: Ich bin absolut neu was Delphi angeht, meine letzten minimalen Schulerfahrungen damit liegen gute 4-5 Jahre zurück, von daher bitte ich um etwas nachsicht, falls ich mich zu dämlich anstelle
Meine Aufgabe ist folgende: ich soll ein Programm schreiben, das über die Konsole mit 3 Parametern aufgerufen wird.
Parameter 1: Das Verzeichnis, wo die Datei liegt
Parameter 2: Der Anfang des Dateinamens
Parameter 3: Die Anzahl von Tagen, die die Datei alt ist (letzte Änderung)
Das Programm soll einfach durchlaufen und alle Dateien in diesem Verzeichnis, die mit dem in Parameter2 genannten Namen beginnen und seit x Tagen nicht mehr geändert wurden löschen, egal ob schreibgeschützt oder nicht. Ich hab das ganze vor ner Weile unter C versucht und bin daran gescheitert, da das Auslesen des Dateialters und die ganzen Datumsgeschichten etwas schwierig sind ... nun scheint es mir, als ob das unter Delphi leichter zu realisieren wäre. Hat jemand eine idee, auf welche funktionen ich da zugreifen müsste? Bisher habe ich folgende Stichwörter dazu gefunden:
- findfirst
- findnext
- paramstring
Ich kenne mich mit Delphi momentan zu wenig aus, um da irgendetwas zu realisieren, bin aber dabei, mich zu belesen. Wenn jemand in der Zwischenzeit Tipps bezüglich dieses Themas hat hilft mir das sicher weiter 
|
|
Agawain
      
Beiträge: 460
win xp
D5, MySQL, devxpress
|
Verfasst: Mo 08.10.07 10:45
Hi
vielleicht hilft Dir das auf die Sprünge.
Was Du außer findfirst brauchst, ist TSearchRec, darin stehen die benötigten Informationen zur Datei.
Diese Funktion liest ein Verzeichnis mit excel-Dateien aus und gibt die Dateinamen, allerdings nur diese in eine checklistbox aus.
Gruß
Aga
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure VerzeichnisEinlesen(dir:string); var SR: TSearchRec; i : integer; begin f_absatz.cxCheckListBox1.Columns := 2; if dir[length(dir)]<>'\' then dir:=dir+'\'; with f_absatz do begin cxCheckListBox1.Items.Clear; i := 0; if FindFirst(dir+'*.xls',faAnyFile,SR)=0 then Begin repeat cxCheckListBox1.items.add; cxCheckListBox1.Items[i].Text := sr.name; i := i + 1; until FindNext(SR)<>0; FindClose(SR); End; end; end; |
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Mo 08.10.07 12:10
Danke, das hat mir wirklich geholfen, nun habe ich erstmal eine Vorstellung
Also im Moment sieht mein Code wie folgt aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| program filedeleter;
uses SysUtils;
procedure DeleteFiles(count:integer); var SR : TSearchRec; var verzeichnis : string; var dateiname : string; var tage : integer; var toleranzdatum : integer;
begin verzeichnis := ParamStr(1); dateiname := ParamStr(2); tage := StrToInt(ParamStr(3)); toleranzdatum := int(date) - tage; if FindFirst(verzeichnis+dateiname+'*',faAnyFile,SR)=0 then Begin repeat if int(FileDateToDateTime(SR.time)) <= toleranzdatum then begin DeleteFile(verzeichnis+SR.name); end; until FindNext(SR)<>0; FindClose(SR); End; end;
end. |
Leider meckert er an Zeile 17:
toleranzdatum := int(date) - tage;
mit folgender Fehlermeldung:
Inkompatible Typen: 'Integer' und 'Extended'.
TDateTime ist ne Extended, ich wüsste aber nicht, wie ich vernünftig mit den Tagen rechnen soll, wenn ich nicht den ganzzahligen Teil abschneide von dem Datumswert. Dann wird das bei FileDateToDateTime mit der Int()-Funktion wohl auch nicht klappen. wenn ich nun also alles mit Double rechne, dann hab ich das Problem, dass ich den Parameterwert 3 ("tage") nicht in double konvertiert kriege, oder reicht da float? Bin grad etwas ratlos...
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mo 08.10.07 12:29
Entweder definierst Du toleranzdatum als extended oder Du schreibst:
Delphi-Quelltext 1:
| toleranzdatum := Trunc(date) - tage; |
in der entsprechenden Code-Zeile (hier 17).
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Mo 08.10.07 12:55
Danke, das hab ich angepasst, er kompiliert es auch vernünftig. Jedoch passiert absolut garnichts, wenn ich die exe mit Parametern aufrufe... habe ich irgendetwas vergessen oder nicht beachtet, vom Grundaufbau her?
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mo 08.10.07 13:22
Delphi-Quelltext 1:
| if FindFirst(verzeichnis+dateiname+'*',faAnyFile,SR)=0 then Begin |
Nagel mich nicht drauf fest, aber was passiert mit Dateien, die noch ein Suffix haben? Ich meine, dass Deine Vorgabe keine Dateien berücksichtigt, die etwas so aussehen: bla*.txt. Das ".txt" kann so nicht gefunden werden.
Was ist außerdem, wenn Dein Parameter für das Verzeichnis keinen abschließenden "\" hat? Dann dürftest Du auch kein Ergebnis haben.
Am besten gehst Du mit dem Debugger schrittweise durch das Programm und schaust Dir mal die Inhalte Deiner Variablen an.
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Mo 08.10.07 15:14
das mit dem +'*' hätte tatsächlich eine Möglichkeit sein können, habe ich jedoch jetzt auf + '*.*' abgeändert, womit das ausgeschlossen sein sollte. auch der "\" am ende wird fleißig mit eingegeben, es ändert jedoch nichts. es passiert einfach nischt  für den "\" überleg ich mir dann später eine kontrollroutine, erstmal musses ja klappen.
deim debuggen funzt irgendwas nicht richtig, er steht immer gleich auf "end" wenn ich umschalt + f7 drück. also wird da irgendwas allgemein falsch laufen ... nur kenn ich mich nicht ausreichend aus, um da den Fehler zu sehen...
|
|
Agawain
      
Beiträge: 460
win xp
D5, MySQL, devxpress
|
Verfasst: Mo 08.10.07 18:15
hi
Zunächst mal Du rufst die Prozedur auf, sorry für meine inkorrekte Definition oben, weil es ja eine Prozedur ist und keine Funktion, mit dem Parameter Count auf, der nirgendwo angesprochen wird und da es sich um eine Konsolenanwendung handelt, vermutlich auch nirgendwo initialisiert wird.
Also die Prozedur erwartet den Parameter Count und der ist nix.
Wundert mich, daß Delphi da nicht noch mehr meckert
Wenn Du Count als Rückgabewert haben willst, mußt Du die Sache als Funktion definieren und natürlich auch noch Count einrichten.
Wahrscheinlich springt er deswegen auch direkt auf end, weil normalerweise müßte er ja eigentlich auf jeden Fall die Parameter übergeben.
Außerdem brauchst Du ja im Hauptprogramm ja einen Aufruf der Funktion *denk, von alleine führt die sich auch nicht aus.
Und das mit dem \ ist in 'meinem' Code *hust, auch mal wieder irgendwo grötemteils geklaut...enthalten.
Gruß
Aga
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Di 09.10.07 08:20
also ich habs mal ohne rückgabewert versucht (also leere klammern), das ändert auch nichts, weil im endeffekt will ich ja garnichts zurückgeben ^^ das wär halt nur die idee gewesen dass er sagt, wie viel gelöscht wurde. aber nichtmal das ist wichtig, hauptsache er tuts. jop, das mit dem "\" hab ich schon gesehen bei dir, aber noch nicht ganz durchgeblickt. das kommt dann auch später, erstmal muss er ja löschen.
das mit dem aufrufen der prozedur macht natürlich sinn, auch wenn ich noch nicht ganz verstehe, wie ich das machen soll ... muss ich die vorab definieren? weil eigentlich soll er doch nur die zeilen runterarbeiten ^^
p.s.: das ist der aktuelle Code
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| program filedeleter;
uses SysUtils;
procedure DeleteFiles(); var SR : TSearchRec; var verzeichnis : string; var dateiname : string; var tage : integer; var toleranzdatum : extended;
begin verzeichnis := ParamStr(1); dateiname := ParamStr(2); tage := StrToInt(ParamStr(3)); toleranzdatum := int(date) - tage; if FindFirst(verzeichnis+dateiname+'*.*',faAnyFile,SR)=0 then Begin repeat if int(FileDateToDateTime(SR.time)) <= toleranzdatum then begin DeleteFile(verzeichnis+SR.name); end; until FindNext(SR)<>0; FindClose(SR); End; end;
end. |
|
|
Agawain
      
Beiträge: 460
win xp
D5, MySQL, devxpress
|
Verfasst: Di 09.10.07 08:44
moin
genau und deswegen läßt Du die Prozedurendeklaration einfach weg.
Bin leider auch Newbie, was Konsolenanwendungen angeht, aber hier ein kleines tut, was Dir vielleicht weiterhilft.
www.lima-city.de/tutorials/show/2091
Gruß
Aga
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Di 09.10.07 09:45
Geil, danke, das hat sogar sehr geholfen  einfach mal die Prozeduranweisung weggelassen und das letzte end wegstreichen ... und hinter das davor nen punkt setzen  nu läuft er auch durch. löschen tut er noch nichts, aber da muss ich einfach mal die Bedingung mit den Tagen nachprüfen *g* Die Werte holt er auch richtig aus den Parametern raus, sofern ich das über die eingebaute Test-Möglichkeit von Delphi herausfinden konnte.
aktueller Stand:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| program filedeleter; {$APPTYPE CONSOLE}
uses SysUtils;
var SR : TSearchRec; verzeichnis : string; dateiname : string; tage : integer; toleranzdatum : extended;
begin verzeichnis := IncludeTrailingBackslash(ParamStr(1)); dateiname := ParamStr(2); tage := StrToInt(ParamStr(3)); toleranzdatum := int(date) - tage; if FindFirst(verzeichnis+dateiname+'*.*',faAnyFile,SR)=0 then Begin repeat if int(FileDateToDateTime(SR.time)) <= toleranzdatum then begin DeleteFile(verzeichnis+SR.name); end; until FindNext(SR)<>0; FindClose(SR); End; end. |
EDIT1: Es klappt tatsächlich  Das Problem war, dass er vom Änderungsdatum ausgeht, nicht vom Erstellungsdatum  Und da ich die Dateien gestern umbenannt habe (123 davor geschrieben), um zu testen, dass er wirklich nur Die anpackt, hat er natürlich das Änderungsdatum hochgesetzt  Also bleibt nurnoch herauszufinden, wie ich das erstellungsdatum ermittle, aber das sollte ja keine Schwierigkeit sein. DANKE für die großartige Hilfe. Sobald die Schleife zum Prüfen auf den "\" am Ende fertig ist, schreibe ich sie noch hier in den Code dazu.
EDIT2: So, die Schleife ist nun drin, ich hab mich da mal selbst um etwas bemüht  Eventuell baue ich später noch soetwas wie eine Hilfe ein, wobei das ja im Moment nicht nötig ist ^^
EDIT3:
Delphi-Quelltext 1: 2: 3: 4:
| verzeichnis := ParamStr(1); if LastDelimiter('\',verzeichnis) <> Length(verzeichnis) then begin verzeichnis := verzeichnis + '\'; end; |
entfernt und dafür
Delphi-Quelltext 1:
| verzeichnis := IncludeTrailingBackslash(ParamStr(1)); |
hinzugefügt
Zuletzt bearbeitet von Insanctus am Di 09.10.07 10:50, insgesamt 3-mal bearbeitet
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 09.10.07 10:10
Insanctus hat folgendes geschrieben: | | Also bleibt nurnoch herauszufinden, wie ich das erstellungsdatum ermittle, |
Schau mal hier:
www.delphi-forum.de/viewtopic.php?t=67069
|
|
Sinspin
      
Beiträge: 1340
Erhaltene Danke: 120
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 09.10.07 10:18
Das Zauberwort zur Ermittlung bzw. zum anhängen des Backslash ist IncludeTrailingBackslash. Mords langer name, aber tut was du brauchst.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Di 09.10.07 10:24
Sinspin hat folgendes geschrieben: | | Das Zauberwort zur Ermittlung bzw. zum anhängen des Backslash ist IncludeTrailingBackslash. Mords langer name, aber tut was du brauchst. |
Danke, die Hilfe erklärt die Funktion ziemlich gut, das machts natürlich noch einfacher als mit meiner so schön herausgearbeiteten Schleife ^^ werd ich gleich mal einbauen!
@jasocul ich schau mal nach  Oh, den Thread hatte ich ganz zu Anfang mal auf aber wieder verworfen, da es ja um FTP Sachen ging ^^ Aber für meinen Anwendungsfall ist das glaube ich nicht so wichtig, da es um das Löschen von alten Datensicherungen geht. Und deren "letzte Änderung"-Datum variiert ja nur um ein paar Stündchen mit dem "Erstellt am" ....  Durchlesen werd ichs mir trotzdem mal in Ruhe.
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Di 09.10.07 14:54
Ich habe etwas Wichtiges vergessen -.- und zwar den Schreibschutz! Schreibgeschützte Dateien werden nicht gelöscht, das soll aber der Fall sein. Das heißt ich muss irgendwo vor der löschung noch prüfen, ob der Schreibschutzt gesetzt ist und diesen gegebenenfalls aufheben. Jemand ne Idee wie das geht? Ich durchforste derweil weiter die Hilfe.
|
|
Insanctus 
Hält's aus hier
Beiträge: 9
|
Verfasst: Di 09.10.07 15:13
Habs schon, FileSetAttr ist das Zauberwort. Damit es nicht zu Verwirrungen kommt hier nochmal der komplette fertige Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| program filedeleter; {$APPTYPE CONSOLE}
uses SysUtils;
var SR : TSearchRec; verzeichnis : string; dateiname : string; tage : integer; toleranzdatum : extended;
begin verzeichnis := IncludeTrailingBackslash(ParamStr(1)); dateiname := ParamStr(2); tage := StrToInt(ParamStr(3)); toleranzdatum := int(date) - tage; if FindFirst(verzeichnis+dateiname+'*.*',faAnyFile,SR)=0 then Begin repeat if int(FileDateToDateTime(SR.time)) <= toleranzdatum then begin if (FileGetAttr(verzeichnis+SR.name) and faReadOnly) > 0 then FileSetAttr(verzeichnis+SR.name, FileGetAttr(verzeichnis+SR.name) xor faReadOnly); DeleteFile(verzeichnis+SR.name); end; until FindNext(SR)<>0; FindClose(SR); End; end. |
|
|
|