Autor Beitrag
Insanctus
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: 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



ausblenden 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); //Nach jedem findfirst nötig, um sr freizugeben!
    End;
  end;
end;
Insanctus Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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:

ausblenden 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); //Nach jedem findfirst nötig, um sr freizugeben!
  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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6395
Erhaltene Danke: 149

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 08.10.07 12:29 
Entweder definierst Du toleranzdatum als extended oder Du schreibst:
ausblenden Delphi-Quelltext
1:
toleranzdatum := Trunc(date) - tage;					

in der entsprechenden Code-Zeile (hier 17).
Insanctus Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6395
Erhaltene Danke: 149

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 08.10.07 13:22 
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: 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 :wink:

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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 09.10.07 09:45 
Geil, danke, das hat sogar sehr geholfen :D 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:

ausblenden 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 :D 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  verzeichnis := ParamStr(1);
  if LastDelimiter('\',verzeichnis) <> Length(verzeichnis) then begin
      verzeichnis := verzeichnis + '\';
  end;

entfernt und dafür
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6395
Erhaltene Danke: 149

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Di 09.10.07 10:10 
user profile iconInsanctus hat folgendes geschrieben:
Also bleibt nurnoch herauszufinden, wie ich das erstellungsdatum ermittle,
Schau mal hier:
www.delphi-forum.de/viewtopic.php?t=67069
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1340
Erhaltene Danke: 120

Win 10
RIO, CE, Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 09.10.07 10:24 
user profile iconSinspin 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 09.10.07 15:13 
Habs schon, FileSetAttr ist das Zauberwort. Damit es nicht zu Verwirrungen kommt hier nochmal der komplette fertige Code:


ausblenden 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)); // Abschließender Backslash wird angehängt, wenn noch nicht vorhanden
  dateiname := ParamStr(2);
  tage := StrToInt(ParamStr(3));                        // Wird von String in Integer konvertiert
  toleranzdatum := int(date) - tage;                    // Toleranz wird vom aktuellen Datum abgezogen
  if FindFirst(verzeichnis+dateiname+'*.*',faAnyFile,SR)=0 then Begin   // Sucht nach allen Dateien in Verzeichnis, die mit Dateiname beginnen
    repeat
        if int(FileDateToDateTime(SR.time)) <= toleranzdatum then begin // Wenn Datei("geändert am") älter als Datum - Toleranz
          if (FileGetAttr(verzeichnis+SR.name) and faReadOnly) > 0  // Wenn Schreibgeschützt
             then FileSetAttr(verzeichnis+SR.name, FileGetAttr(verzeichnis+SR.name) xor faReadOnly); // Schreibschutz aufheben
          DeleteFile(verzeichnis+SR.name);              // Löschen der Datei
        end;
    until FindNext(SR)<>0;                              // Bis keine weitere Datei Vorhanden
    FindClose(SR);                                      // Suche beenden
  End;
end.