Autor Beitrag
Horschdware
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 744
Erhaltene Danke: 54

Win XP Pro, Win 7 Pro x64
Delphi 7, Delphi XE, C++ Builder 5, SAP R/3
BeitragVerfasst: Mi 29.03.06 14:07 
Hallo,
ich versuche gerade mein Programm die älteste Datei in einem Verzeichnis finden zu lassen.
Dazu durchsuche ich zuerste das Verzeichnis und speichere die Dateinamen in eine StringList.
Dann soll die StringList sortiert werden. Dies mache ich per insert sort und nutze die IsNewerThan Funtkion,
die prüft ob FileName1 neuer ist als Nummer 2.

Leider sortiert das nicht richtig.
Ich weiss aber nicht warum.
Habe ich evtl irgendwo einen Denkfehler?

Kann mir jemand weiterhelfen?

Ach ja: Das ganze geht in der Konsole von statten und "AllOptions" ist ein globales record,
in dem in der Variable "FileName" ein Ziel-Datei-name inkl. Pfad gespeichert ist.

edit: Aufgerufen wird im Programmablauf die function "GetOldestFile".

ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
function IsNewerThan(FileName1 : string; FileName2 : string) : boolean;
var
  FileDate: Integer;
  DateTime1: TDateTime;
  DateTime2: TDateTime;
  iDate1 : int64;
  iDate2 : int64;
begin

  // Die zu vergleichenden Dateien müssen existieren
  if (FileExists(FileName1) AND FileExists(FileName2))
  then
  begin

    // Für beide Dateien FileAge auslesen und in TDateTime umwandeln
    FileDate := FileAge(FileName1);
    DateTime1 := FileDateToDateTime(FileDate);

    FileDate := FileAge(FileName2);
    DateTime2 := FileDateToDateTime(FileDate);

    // TDateTime in Strings umwandeln YYYYMMDD
    iDate1 := StrToInt(FormatDateTime('yyyymmdd',DateTime1));
    iDate2 := StrToInt(FormatDateTime('yyyymmdd',DateTime2));

    // Neueres Datum müsste nun höheren Integerwert besitzen
    //  20060320 > 20060301
    if iDate1 > iDate2 then result:=true
      else result:=false;

  end
  else result:=false;  // Falls es nichts zu vergleichen gibt...
end;

function GetOldestFile(path : string) : string;
var AllFiles : TStringList;
    rec :  TSearchRec;
    i : integer;
    temp : string;
begin
  // Stringliste aufmachen
  AllFiles:=TStringList.create;

  // Falls es Dateien gibt, weitersuchen und erstes Ergebnis gleich speichern
  if FindFirst(IncludeTrailingPathDelimiter(ExtractFilePath(Alloptions.Filename))+'*.*',faAnyFile,rec) = 0 then
  begin
    AllFiles.Add(rec.Name);
    // Solange es weitere Dateien gibt weitermachen
    while FindNext(rec) = 0 do
      AllFiles.Add(rec.Name);

    // Suche beenden
    FindClose(0);
  end;

  // Start bei Index 0 der Stringliste
  i:=0;
  // Solange High nicht erreicht wurde...
  while i< AllFiles.Count-1 do
  begin
    // Ist Element i neuer als Element i+1 ?
    if IsNewerThan(IncludeTrailingPathDelimiter(ExtractFilePath(Alloptions.Filename))+AllFiles[i],
                   IncludeTrailingPathDelimiter(ExtractFilePath(Alloptions.Filename))+AllFiles[i+1]) then
    begin
      // Dann Austauschsortierung
      temp:=AllFiles[i];
      AllFiles[i]:=AllFiles[i+1];
      AllFiles[i+1]:=temp;
      i:=0;
    end
    else inc(i);  // Ansonsten weiter zum nächsten i
   end;

   // Ausgabe
   for i:=0 to AllFiles.Count-1 do
     writeln(AllFiles[i]);

  // StringList wieder freigeben
  AllFiles.free;
end;

_________________
Delphi: XE - OS: Windows 7 Professional x64
Vera
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 82

WinXP Home
Delphi 2005 Personal
BeitragVerfasst: Mi 29.03.06 16:24 
Hallo!

Versuche mal folgenden Sourcecode. Die geänderten Stellen habe ich markiert:
ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
function IsNewerThan(FileName1 : string; FileName2 : string) : boolean;
begin
  IsNewerThan := FileExists(FileName1) AND FileExists(FileName2) and
    (FileAge (FileName1) > FileAge (FileName2));
end;


function GetOldestFile(path : stringaItems : tStrings) : string;
var AllFiles : TStringList;
    rec :  TSearchRec;
    i1,i2 : integer;
    temp : string;
begin
  AllFiles:=TStringList.create;

  if FindFirst(IncludeTrailingPathDelimiter(path)+'*.*',faAnyFile,rec) = 0 then
  begin
    AllFiles.Add(rec.Name);
    while FindNext(rec) = 0 do
      AllFiles.Add(rec.Name);

    FindClose(rec);
  end;

  for i1 := 0 to AllFiles.Count-1 do
    for i2 := i1 +1 to AllFiles.Count-1 do
      if IsNewerThan(IncludeTrailingPathDelimiter(Path)+AllFiles[i1],
                     IncludeTrailingPathDelimiter(Path)+AllFiles[i2]) then
      begin
        temp:=AllFiles[i1];
        AllFiles[i1]:=AllFiles[i2];
        AllFiles[i2]:=temp;
      End;


   // Ausgabe
   for i1:=0 to AllFiles.Count-1 do
     aItems.Add (AllFiles[i1]);

  // StringList wieder freigeben
  AllFiles.free;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetOldestFile ('c:\misc', ListBox1.Items);
end;
Horschdware Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 744
Erhaltene Danke: 54

Win XP Pro, Win 7 Pro x64
Delphi 7, Delphi XE, C++ Builder 5, SAP R/3
BeitragVerfasst: Mi 29.03.06 18:04 
Aaaalsoo....
ich hab das ganze nochmal überdacht und mach es jetzt einfach ne runde einfacher.
ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
function GetFile(path : string; mode : string = 'NEW') : string;
//  Gibt den Namen der ältesten oder neusten Datei ohne
//  Pfad als String zurück.
//  Um die älteste Datei zu erhalten mode auf 'OLD' setzen.
//  Um die neuste Datei zu erhalten mode auf 'NEW' setzen.
//
//  Benutze FileRec zum Speichern der Paare DateiName/Datum
//
//  type
//     FileRec = record
//       FileName : string;
//       iDate : int64;
//     end;
//------------------------------------------------------------------------------
  function GetFileDate(filename : string) : int64;
  var DateTime: TDateTime;
      FileDate: Integer;
  begin
    if FileExists(filename) then
      begin
        FileDate := FileAge(filename);
        DateTime := FileDateToDateTime(FileDate);
        result:=StrToInt(FormatDateTime('yyyymmdd',DateTime));
      end
    else
      result:=-1;
  end;
//------------------------------------------------------------------------------
var AllFiles : array of FileRec;
    rec :  TSearchRec;
    i : integer;
    temp : FileRec;
begin
  setlength(AllFiles,1);

  // Falls es Dateien gibt, weitersuchen und erstes Ergebnis gleich speichern
  if FindFirst(IncludeTrailingPathDelimiter(ExtractFilePath(Alloptions.Filename))+'*.*',faAnyFile,rec) = 0 then
  begin
    AllFiles[high(AllFiles)].FileName:=rec.Name;
    AllFiles[high(AllFiles)].iDate:=GetFileDate(IncludeTrailingPathDelimiter(ExtractFilePath(Alloptions.Filename))+rec.name);

    // Solange es weitere Dateien gibt: weitermachen
    while FindNext(rec) = 0 do
    begin
       setlength(AllFiles,high(AllFiles)+2);
       AllFiles[high(AllFiles)].FileName:=rec.Name;
       AllFiles[high(AllFiles)].iDate:=GetFileDate(IncludeTrailingPathDelimiter(ExtractFilePath(Alloptions.Filename))+rec.name);
    end;
    // Suche beenden
    FindClose(0);
  end;

  // Start bei Index 0 des Arrays
  i:=0;

  // Solange High nicht erreicht wurde...
  while i < high(AllFiles) do
  begin
    // Ist Element i neuer als Element i+1 ?
    if AllFiles[i].iDate > AllFiles[i+1].iDate then
    begin
      // Dann Austauschsortierung
      temp:=AllFiles[i];
      AllFiles[i]:=AllFiles[i+1];
      AllFiles[i+1]:=temp;
      i:=0;
    end
    else inc(i);  // Ansonsten weiter zum nächsten i
   end;

   // Ordner werden vorraussichtlich iDate -1 bekommen
   // -> Bei Ausgabe nicht beachten
   i:=0;
   repeat
     inc(i);
   until AllFiles[i].iDate > -1;

   // Ausgabe, mode-abhängig
   if (mode='OLD'then
     result:=AllFiles[i].FileName
   else
     result:=AllFiles[high(AllFiles)].FileName;
end;


Ich sortiere dann einfach das Array durch und gut ists.
@Vera: Du machst bei dir "FindClose(rec)"
lt. Debugger kann ich das nicht, da FindClose den Datentyp Cardinal erwartet.
Irgendwie merkwürdig...
Danke aber mal für deine Lösung.

_________________
Delphi: XE - OS: Windows 7 Professional x64