![]() |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Ist das hier auch OK?
Delphi-Quellcode:
Ein erster Test:
// ...
if WithSubDirs then sFileDate := ',' + FloatToStr(SR.TimeStamp) else sFileDate := ''; List.Add(SR.Name + sFileDate); // Ich will nur die Dateinamen mit SubbDir in der Liste haben (SR.Name) // ... - Ein Vergleich von 10.000 Dateien im Quell- UND Zielverzeichnis dauert mit "sFileDate" da oben ~ 24 bis 26 Sekunden. - mit dem Vergleich "if getFileLastModified(aFileA) > getFileLastModified(aFileB) then" in etwa 130 Sekunden. Denkt ihr, 24 Sekunden sind erträglich? Bedenke: Quell-Verzeichnis ist die HDD im PC, Zielverzeichnis die HDD am Router (also langsam). Von C nach D gehts schneller (~12 Sekunden). |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Und für den Vergleich puzzelst du den String wieder auseinander? Nimm ein Records, die du in einer Lsite verwaltest oder eine Obejctlist. Dann wird es sauber.
|
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Ich habe gerade eine schöne Lösung mit einem TDynArray und einem Record gefunden. Aber ich finde ums Verrecken nicht, wo TDynArray deklariert ist.
Ok das lasse ich lieber sein. Das wirft mir alles durcheinander. Ich versuche das mal mit einem Record und einer ObjectList. |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Zitat:
Delphi-Quellcode:
findest du viele Arraytypen. Aber bastle dir doch dein eigenes dynamisches Array.
System.Types
|
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Habe das gerade mal mit einem Record probiert, den ich in eine TStrings packe (AddObject).
Klappt alles wunderbar. Aber jetzt klappt IndexOf der Liste natürlich nicht mehr. Das fand ich recht angenehm vorher. Ich sehe gerade erst, dass IndexOf ja auch nicht klappt und immer -1 zurückgibt, wegen meiner SR.Name+Datum-Konstruktion. Edit: Ich hab es jetzt ganz schön (für mich) hinbekommen. Jetzt ist aber plötzlich das Problem aufgetreten, dass die Zieldaten, welche eine Kopie der Quelldaten sind, angeblich nicht gleich sind vom Datum her. Siehe hier: Zitat:
Edit #2: Problem hat sich von alleine gelöst. Ich glaube die Festplatte raucht ab. War vorherzusehen. |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Irgendwie vergewaltigst du da gerade eine Stringlist. :roll: AdObjekct der Stringliste nimmt man zusätzlich zu den anzuzeigenden noch zusätzlich Daten speichern will.
Entweder dynamisches Array mit Records oder eine Objectlist mit Objekten. Mit welchen Dateisystemen haben wir es zu tun? FAT und NTFS habe unterschiedliche Auflösungen, was den Timestamp betrifft: ![]() |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Beides NTFS.
Zur StringList. Ja ich weiß, nicht gut. Aber auf diese Art und Weise kann ich die Funktion ( GetFilesInDirectory ) mit und ohne Record benutzen:
Delphi-Quellcode:
Ich weiß. Der Variablenname ist total missverständlich aber so funktioniert es:
procedure GetFilesInDirectory(Directory: string; const Mask: string; List: TStrings; WithSubDirs, AsObjectList, ClearList: Boolean);
Delphi-Quellcode:
type
PFileListEntry = ^TFileListEntry; TFileListEntry = packed record sFileName: string; iFileSize: Int64; iFileDate: Extended; end; procedure GetFilesInDirectory(Directory: string; const Mask: string; List: TStrings; WithSubDirs, AsObjectList, ClearList: Boolean); var aFileListEntry: PFileListEntry; procedure ScanDir(const Directory: string); var SR: TSearchRec; begin if FindFirst(Directory + Mask, faAnyFile and not faDirectory, SR) = 0 then try repeat Application.ProcessMessages; /// ////////////////////////////////////////////////////////////////////////////////// if AsObjectList then begin System.New(aFileListEntry); aFileListEntry.sFileName := SR.Name; aFileListEntry.iFileSize := SR.Size; aFileListEntry.iFileDate := SR.TimeStamp; List.AddObject('F_' + SR.Name, Pointer(aFileListEntry)); end else begin List.Add(SR.Name); end; /// ////////////////////////////////////////////////////////////////////////////////// until FindNext(SR) <> 0; finally FindClose(SR); end; if WithSubDirs then begin if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try repeat Application.ProcessMessages; if ((SR.attr and faDirectory) = faDirectory) and (SR.Name <> '.') and (SR.Name <> '..') then ScanDir(Directory + SR.Name + ''); until FindNext(SR) <> 0; finally FindClose(SR); end; end; end; begin List.BeginUpdate; try if ClearList then List.Clear; if Directory = '\' then Exit; if Directory[Length(Directory)] <> '\' then Directory := Directory + '\'; ScanDir(Directory); finally List.EndUpdate; end; end; function IndexOfListObjects(const s: string; List: TStringList): Integer; begin for Result := 0 to List.Count - 1 do if s = PFileListEntry(List.Objects[Result])^.sFileName then Exit; Result := -1; end; procedure TForm1.Button1Click(Sender: TObject); var freq: Int64; startTime: Int64; endTime: Int64; i, iDestFileIndex: Integer; sSourceDir, sDestDir: String; slSource, slDest: TStringList; aFileListEntrySource, aFileListEntryDest: TFileListEntry; begin QueryPerformanceFrequency(freq); QueryPerformanceCounter(startTime); slSource := TStringList.Create; slDest := TStringList.Create; try sSourceDir := 'D:\Test1\'; // behinhaltet 10.000 Dateien sDestDir := 'D:\Test2\'; // behinhaltet ebenfalls 10.000 Dateien, welche identisch sind GetFilesInDirectory(sSourceDir, '*.*', slSource, True, True, False); GetFilesInDirectory(sDestDir, '*.*', slDest, True, True, False); for i := 0 to slSource.Count - 1 do begin Application.ProcessMessages; aFileListEntrySource := PFileListEntry(slSource.Objects[i])^; iDestFileIndex := IndexOfListObjects(aFileListEntrySource.sFileName, slDest); if iDestFileIndex > -1 then begin aFileListEntryDest := PFileListEntry(slDest.Objects[iDestFileIndex])^; if aFileListEntrySource.iFileDate > aFileListEntryDest.iFileDate then begin // Tue was auch immer mit aFileListEntrySource end; end; end; // for finally for i := 0 to slSource.Count - 1 do Dispose(PFileListEntry(slSource.Objects[i])); for i := 0 to slDest.Count - 1 do Dispose(PFileListEntry(slDest.Objects[i])); slSource.Free; slDest.Free; end; QueryPerformanceCounter(endTime); showmessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + 'ms'); end; |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Timestamp ist garantiert nicht vom exotischen Typ Extended. Das sollte TDateTime sein.
Wenn du Zahlen in unterschiedliche Typen packst, hast du auch unterschiedliche Genauigkeiten und damit Rundungsfehler. Wann gibst du den Speicher für die Records eigentlich wieder frei? Und warum benutzt du nicht Klassen, die du ohne Pointerspielerei direkt in AddObject packen kannst? Und mit OwnsObjects auf True (Standard im Konstruktor) werden die auch automatisch wieder freigegeben. |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Zitat:
Wa genau meinst du mit Klasse statt Pointer. Muss man den Speicher für die Records nicht wieder freigeben? Ich dachte, wenn ich datensätze erzeuge und ich sie verwendet habe, dass ich den Speicher freigeben muss. Habe jetzt jedenfalls von Extened to TDateTime geändert. Ich dachte vorher, ich nehme Extended weil es genauer ist. |
AW: FileExists/FileDate - Auslesen über Netzwerk langsam
Er meinst so was:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz