Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   FileExists/FileDate - Auslesen über Netzwerk langsam (https://www.delphipraxis.net/190199-fileexists-filedate-auslesen-ueber-netzwerk-langsam.html)

dGeek 10. Sep 2016 18:30


FileExists/FileDate - Auslesen über Netzwerk langsam
 
Ich benutze aktuell folgenden Schnipsel, um das Änderungsdatum einer Datei herauszufinden:

Delphi-Quellcode:
function getFileLastModified(const aFileName: string): TDateTime;
var
 SR: TSearchRec;
begin
 Result := 0;

 try
  FindFirst(aFileName, faAnyFile, SR);
  Result := SR.TimeStamp;
 except
 end;
end;
Die Funktion scheint etwas lahm zu sein, wenn man viele Dateien prüft, die auf einer Festplatte im Netzwerk liegen.
Gibt es da nichts Schnelleres? Speziell wenn aFileName nicht existiert ist das sehr langsam.

Letztendlich bin ich mir nicht sicher, ob es vielleicht doch FileExists() ist, welches über Netzwerk langsam ist.

zeras 10. Sep 2016 18:39

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Kannst du nicht die Dateien mit Findfirst und FindNext auslesen und nicht jedesmal mit deiner Funktion eine neue Suche starten, wo wieder jedes Mal Findfirst vorkommt?
Oder kann man die Dateien nicht mit einer generellen Suche Beispiel "*.txt" suchen?

dGeek 10. Sep 2016 18:43

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Die Dateiliste existiert bereits.

Erklärung:

Verzeichnis Quelle hat:
- Datei1
- Datei2
- Datei3

Verzeichnis Ziel (Festplatte im Netzwerk):
- Datei1


Datei2 und - Datei3 fehlen im Netzwerk also.

Jetzt wird durch die Quellliste iteriert:

von 0 bis Listenende-1 tue
- Wenn Quelle+DateiN neuer als Ziel+DateiN dann .... (IsFileANewerFileB)

Die Vergleichsfunktion:
Delphi-Quellcode:
function IsFileANewerFileB(aFileA, aFileB: string): Boolean;
var
 bRes: Boolean;
begin
 if (not FileExists(aFileB)) or (not FileExists(aFileA)) then
  bRes := True
 else
  bRes := getFileLastModified(aFileA) > functions.getFileLastModified(aFileB);

 Result := bRes;
end;

function getFileLastModified(const aFileName: string): TDateTime;
var
 SR: TSearchRec;
begin
 Result := 0;

 FindFirst(aFileName, faAnyFile, SR);
 Result := SR.TimeStamp;
end;
Und ich bin mir nicht sicher, was hier so extremst abbremst. Ich denke aber, es ist FileExists.
Denn wenn ich FileExists() weglasse und getFileLastModified auc, dann ist es superschnell.
Ich schätze mal, dass FindFirst intern auch irgendwie FileExists aufruft.

Luckie 10. Sep 2016 18:44

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Also erst mal könnte man den leeren Exception Block in die Tonne kloppen.
1. Überflüssig, wenn so wieso leer.
2. FindFirst wirft keine Execption: http://docs.embarcadero.com/products...FindFirst.html

Ergo total überflüssig.

Aber ohne näher Angaben über das Netzwerk (Auslastung, Größe, Server, Freigaben, Samba? wird man nicht viel dazu sagen können.

dGeek 10. Sep 2016 18:52

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Ich würde es eher Spielerei nennen :lol:

Es ist eine ganz normale Western Digital Festplatte an einem USB-Port meines Routers.
Wenn ich eine große Datei auf die Festplatte kopiere, so geschieht das mit den erwarteten 100 Megabit (~11 MByte sagt Windows)

nahpets 10. Sep 2016 18:54

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Also Delphi 7 kennt die Funktion FileAge, die Hilfe schreibt dazu:
Zitat:

Die Funktion gibt den Zeitstempel des Betriebssystems von einer Datei zurück.

Unit

SysUtils

Kategorie

Dateiverwaltung

Delphi-Syntax:

function FileAge(const FileName: string): Integer;

Beschreibung

Mit FileAge können Sie den Betriebssystem-Zeitstempel der in FileName angegebenen Datei ermitteln. Der Rückgabewert kann anschließend mit der Funktion FileDateToDateTime in ein TDateTime-Objekt konvertiert werden. Ist die angegebene Datei nicht vorhanden, wird der Wert -1 zurückgegeben.
Würde dann nicht sowas reichen?
Delphi-Quellcode:
function IsFileANewerFileB(aFileA, aFileB: string): Boolean;
begin
  Result := FileAge(aFileA) > FileAge(aFileB);
end;

dGeek 10. Sep 2016 18:59

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Verstehe ich nicht. Egal ob FindFirst oder FileAge. Alles gleich langsam.
In 15 Sekunden prüft er ~2700 Dateien (Durchgänge).

Wenn Quelle und Ziel eine fest im PC installierte Festplatte sind, dauert das ganze keine 3 Sekunden mit 10.000 Durchgängen.

Dalai 10. Sep 2016 20:38

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Die Geschwindigkeit des Netzwerks spielt hier eine stark untergeordnete Rolle. Wichtig ist die Latenz, und die ist nunmal in einem Netzwerk um Faktoren größer als bei einer lokal verbauten Platte. Und wenn es dann noch ein Plasterouter ist, sieht die Welt eh wieder anders aus (lies: Latenz noch größer), denn das sind nunmal keine NAS oder ähnliche auf LAN und SMB optimierte Geräte.

Grüße
Dalai

dGeek 10. Sep 2016 21:42

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Nur wie machen das dann Programme wie FreeFileSync.
Mit dem Programm kann ich 10000 Dateien von meiner im PC befindlichen Festplatte mit 10000 Dateien von der Festplatte im Netzwerk in etwa 10 Sekunden vergleichen.
Das Programm vergleicht auch Datum oder Inhalt. Genau wie ich. Nur ich bin irgendwie zu blöd :lol:

RWarnecke 10. Sep 2016 21:56

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zu FreeFileSync gibt es auch den Quelltext, schaue da doch mal rein, wie die das machen. Wenn ich das richtig weiß und auch richtig beobachtet habe gehen die bei FreeFileSync über mehrere Threads die parallel laufen.

dGeek 10. Sep 2016 22:06

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Mh ja ok. Ich arbeite die 10000 Dateien (eine StringListe) in nur in einem Thread ab.

Hier wäre jetzt die Parallel Library von XE7 schön denke ich.

himitsu 11. Sep 2016 00:00

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Keinem ist das fehlende FindClose aufgefallen?
10.000 offene Such-Handlesmachen sich bestimmt gut.

Nja, wenn es langsam ist, dann würde ich wenigstens die Dateiliste sortieren und Dateien im gleichen Verziechnis auch mit dem gleichen FindFirst+FindNext suchen.

dGeek 11. Sep 2016 00:16

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Nja, wenn es langsam ist, dann würde ich wenigstens die Dateiliste sortieren und Dateien im gleichen Verziechnis auch mit dem gleichen FindFirst+FindNext suchen.
Nicht das Suchen der Dateien ist das Problem. Dafür habe ich eine andere Funktion - von Luckie.

Das Problem ist eher, dass der Datums-Vergleich von 10.000 Dateien über das Netzwerk komischerweise solange dauert.

Zu den Handles: ich benutze mittlerweile folgende Anpassung:
Delphi-Quellcode:
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var
 ModifiedTime: TFileTime;
 SystemTime: TSystemTime;
begin
 Result := 0;
 if (FileTime.dwLowDateTime = 0) and (FileTime.dwHighDateTime = 0) then
  Exit;
 try
  FileTimeToLocalFileTime(FileTime, ModifiedTime);
  FileTimeToSystemTime(ModifiedTime, SystemTime);
  Result := SystemTimeToDateTime(SystemTime);
 except
  Result := Now; // Something to return in case of error
 end;
end;

function getFileLastModified(const aFileName: string): TDateTime;
begin
 Result := FileTimeToDateTime(JclFileUtils.GetFileLastWrite(aFileName));
end;

Luckie 11. Sep 2016 00:40

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Es wird nie eine Exception auftreten. Guck doch mal in der Doku zu den Funktionen, die du nutzt. API Funktionen werfen keine Exceptions, sondern habe Rückgabewerte.

dGeek 11. Sep 2016 10:47

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Ist abgeändert.

Das Hauptproblem besteht aber noch immer und ich krieg nicht raus warum :(
Es liegt aber definitiv an FileExists und dem netzwerk. Andere Programme sind da extrem viel schneller.

zeras 11. Sep 2016 11:47

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347384)
Ist abgeändert.

Das Hauptproblem besteht aber noch immer und ich krieg nicht raus warum :(
Es liegt aber definitiv an FileExists und dem netzwerk. Andere Programme sind da extrem viel schneller.

Da die anderen auch nicht zaubern können, muss wohl die Threadbearbeitung den Schub bringen.

t.roller 11. Sep 2016 11:47

AW: FileExists/FileDate - Auslesen ber Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347356)
Es ist eine ganz normale Western Digital Festplatte an einem USB-Port meines Routers.
Wenn ich eine große Datei auf die Festplatte kopiere, so geschieht das mit den erwarteten 100 Megabit (~11 MByte sagt Windows)

Ein Netzwerk mit 100 Megabit ist für eine Festplatte sehr langsam.
Gibt es beim USB-Port auch eine Möglichkeit zu wählen, ob "schnelles Entfernen" oder "mit Cache"?
Das macht einen Unterschied um den Faktor 3.

jaenicke 11. Sep 2016 12:12

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Das ganze ist sehr einfach:
Andere Tools (auch meine) gehen die beiden Dateilisten einmal durch, speichern die Daten alle und vergleichen danach. Daher ist nur ein Abruf der Dateiliste nötig und die Dateidaten (Dateiname, -größe, -datum) sind ja in dieser Liste mit drin.

Du scheinst hingegen zuerst die Liste abzurufen und dann für jede Datei noch einmal die Dateiliste anzufragen um die Datumsinformationen zubekommen, zu fragen ob sie existiert, ... das dauert ewig.

dGeek 11. Sep 2016 12:17

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

speichern die Daten alle und vergleichen danach.
Du meinst, dein Programm kopiert die Quelldaten zum Zielverzeichnis und DANACH wird erst geguckt, was im Zielverzeichnis gebraucht wird?

Bei mir ist es so:

ich gehe die Liste der Quelldaten einmal durch.
Dann wird immer geguckt:
- "Gibt es Quell-DateiX auch im Zielverzeichnis? (FileExists)
- JA > Quelldatei mit Zieldatei vergleichen (Datum)
- Quelldatei neuer als Zieldatei? JA > in eine andere Liste schreiben (keine StringList...)

Lasse ich FileExists und den Datumsvergleich weg, ist alles wunderbar zackig schnell.
Seltsam ist ja nur.. es ist NUR von PC-HDD zu Netzwerk-HDD langsam.

zeras 11. Sep 2016 12:36

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347389)
Zitat:

speichern die Daten alle und vergleichen danach.
Du meinst, dein Programm kopiert die Quelldaten zum Zielverzeichnis und DANACH wird erst geguckt, was im Zielverzeichnis gebraucht wird?

Ich denke, jaenicke scannt Quell und Zielverzeichnis in einem Ruck durch und prüft dann, welche Unterschiede es gibt. Danach wird dann kopiert oder eben nicht.

Luckie 11. Sep 2016 12:50

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
1. Daten sammeln (Dateien einmal scannen und die Daten in eine Liste ablegen)
2. Gesammelten Daten vergleichen und zu kopierende Dateien in einer Liste ablegen
3. Dateien nach der Liste kopieren

Was du machst:
1. Einzelne Datei scannen
2. Vergleichen
3. Kopieren
Es muss also für jede einzelne Datei alles immer wieder neu initialisiert werden.

dGeek 11. Sep 2016 15:53

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von Luckie (Beitrag 1347394)
1. Daten sammeln (Dateien einmal scannen und die Daten in eine Liste ablegen)
2. Gesammelten Daten vergleichen und zu kopierende Dateien in einer Liste ablegen
3. Dateien nach der Liste kopieren

Was du machst:
1. Einzelne Datei scannen
2. Vergleichen
3. Kopieren
Es muss also für jede einzelne Datei alles immer wieder neu initialisiert werden.


Ich sammle erst alle Daten (Quelle) und speichere sie in einer Liste (das geht schnell). Danach gehe ich die Liste durch und prüfe
- gibt es Quell-Datei1 auch im Zielverzeichnis.
https://www.delphi-treff.de/tipps-tr...ateien-suchen/

Daraus baue ich eine neue Liste und die wird später abgearbeitet (Daten werden kopiert).
Anders wüsste ich nicht, wie man Daten vergleichen soll.

zeras 11. Sep 2016 16:03

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347401)

Ich sammle erst alle Daten (Quelle) und speichere sie in einer Liste (das geht schnell).

Mache doch das gleiche mit deinem Zielsystem. Wie lange dauert denn das?

Sammle die vorhandenen Infos aus dem Ziel und vergleiche diese mit dem Quellsystem. Bei Differenzen musst du dann reagieren und gegebenenfalls kopieren.

dGeek 11. Sep 2016 16:06

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Guck mal mein Beispiel. Nicht das Sammeln der Daten ist das Problem :)

Kleines Beispiel. Es wurde alles weggelassen bis auf das, wo es hapert.
Das hier braucht rund 23 Sekunden (D:\ = im PC, Y:\ = Festplatte am Router per USB 100 MBit): (keine der Dateien existiert)
Delphi-Quellcode:
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var
 ModifiedTime: TFileTime;
 SystemTime: TSystemTime;
begin
 Result := 0;
 if (FileTime.dwLowDateTime = 0) and (FileTime.dwHighDateTime = 0) then
  Exit;

 FileTimeToLocalFileTime(FileTime, ModifiedTime);
 FileTimeToSystemTime(ModifiedTime, SystemTime);
 Result := SystemTimeToDateTime(SystemTime);
end;

function getFileLastModified(const aFileName: string): TDateTime;
begin
 Result := FileTimeToDateTime(JclFileUtils.GetFileLastWrite(aFileName));
end;

function IsFileANewerFileB(aFileA, aFileB: string): Boolean;
var
 bRes: Boolean;
begin
 if (not FileExists(aFileB)) or (not FileExists(aFileA)) then
  bRes := True
 else
  bRes := getFileLastModified(aFileA) > getFileLastModified(aFileB);

 Result := bRes;
end;

/////////////////////////////////////////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
var
 freq: Int64;
 startTime: Int64;
 endTime: Int64;
 i: Integer;
 a, b: String;
begin
 QueryPerformanceFrequency(freq);
 QueryPerformanceCounter(startTime);

 a := 'D:\Datei1.txt';
 b := 'Y:\Datei2.txt';

 for i := 0 to 9999 do
  begin
   if IsFileANewerFileB(a, b) then
    begin
    end;
  end;

 QueryPerformanceCounter(endTime);

 ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + 'ms');
end;
/////////////////////////////////////////////////////////////////////////////////
Wenn Y:\ durch D:\ ausgetauscht wird, dauert das Ganze 50ms.

zeras 11. Sep 2016 16:39

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Du solltest einen kompletten Scan auf dem Quellsystem (FindFirst, FindNext, FindClose) machen und das gleiche auf dem Zielsystem. Dann hast du 2 Listen, die du vergleichen kannst. Dann musst du entscheiden, was gemacht werden soll.
Im Moment machst du das mit jeder Datei einzeln,
FileExists, FileTimeToDateTime etc. Das wird dir wohl die Zeit kosten.


Nimm doch einmal
FindFirst, FindNext, FindClose und prüfe deine Zeit lokal und im Netz. Das andere ist nur Rechnerei auf deinem PC, was nicht die Welt an Zeit kosten wird.

dGeek 11. Sep 2016 16:46

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Ich verstehe diesen Ansatz nicht so ganz.

Wenn ich das so mache wie du sagst, dann muss ich die Dateien ja trotzdem gegenprüfen und gucken, ob DateiX im Zielverzeichnis existiert usw.

zeras 11. Sep 2016 17:04

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347407)
Ich verstehe diesen Ansatz nicht so ganz.

Wenn ich das so mache wie du sagst, dann muss ich die Dateien ja trotzdem gegenprüfen und gucken, ob DateiX im Zielverzeichnis existiert usw.

Nein, da du ja mit FindFirst, FindNext und FindClose schon weißt, ob die Datei da ist.

Wie gesagt, Quelle scannen in eine Liste, Ziel scannen in eine weitere Liste und die Listen dann gegeneinander abgleichen.
Dann hast du nur 1x einen scan in der Quelle und ein scan im Ziel.

Hier ein Beispiel mit Suche von Verzeichnissen. In der StringList (SL) stehen dann erst einmal die Dateinamen. Gegebenenfalls noch das Datum mit dranhängen oder anderweitig speichern.
Das machst du in der Quelle und im Ziel.

Delphi-Quellcode:
            if SysUtils.FindFirst(Dir + '*.*', SysUtils.faDirectory, SR2) = 0 then
              repeat
                if ((SR2.attr and faDirectory) = faDirectory)
                then

                SL.Add();
              until SysUtils.FindNext(SR2) <> 0;
            finally
              FindClose(SR2);
            end;

dGeek 11. Sep 2016 17:20

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Jetzt hab ich es endlich kapiert :wall:
Also von der Logik her ungefähr so?

- erstelle Liste "Quelle"
- erstelle Liste "Ziel"

- iteriere durch Liste "Quelle"
-- prüfe, z.B. mit IndexOf (StringList), ob Eintrag N der Liste "Quelle" in Liste "Ziel" ist
--- wenn ja > weitere Prüfungen (Datumsvergleich)

Bitte sag mir, dass ich es kapiert habe :stupid:

zeras 11. Sep 2016 17:25

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347410)
Jetzt hab ich es endlich kapiert :wall:
Also von der Logik her ungefähr so?

- erstelle Liste "Quelle"
- erstelle Liste "Ziel"

- iteriere durch Liste "Quelle"
-- prüfe, z.B. mit IndexOf (StringList), ob Eintrag N der Liste "Quelle" in Liste "Ziel" ist
--- wenn ja > weitere Prüfungen (Datumsvergleich)

Bitte sag mir, dass ich es kapiert habe :stupid:

Ja so sollte es klappen. Am besten, man merkt sich beim Scannen gleich noch das Datum der letzten Änderung. Ansonsten musst du dann nochmal scannen wegen des Datums. Aber mach doch mal einen Test und gib die Scanzeiten von Quelle und Ziel durch.

Luckie 11. Sep 2016 17:56

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Die Listen enthalten natürlich die erforderlichen Daten zum Vergleichen. Entweder ein Array mit Records oder besser eine Objektliste.

dGeek 11. Sep 2016 18:07

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Ist das hier auch OK?

Delphi-Quellcode:
// ...
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 erster Test:
- 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).

Luckie 11. Sep 2016 18:24

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.

dGeek 11. Sep 2016 18:42

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.

zeras 11. Sep 2016 19:08

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

Zitat von dGeek (Beitrag 1347416)
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.

In
Delphi-Quellcode:
System.Types
findest du viele Arraytypen. Aber bastle dir doch dein eigenes dynamisches Array.

dGeek 11. Sep 2016 19:18

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:

file_100 - Kopie.txt
41706,8549092014
41706,8549074074
Wie kann das sein, obwohl es eine exakte Kopie ist und selbst Windows sagt, das Datum ist gleich.

Edit #2:
Problem hat sich von alleine gelöst. Ich glaube die Festplatte raucht ab. War vorherzusehen.

Luckie 11. Sep 2016 22:06

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: https://blogs.msdn.microsoft.com/old...6-00/?p=40473/

dGeek 11. Sep 2016 22:23

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:
procedure GetFilesInDirectory(Directory: string; const Mask: string; List: TStrings; WithSubDirs, AsObjectList, ClearList: Boolean);
Ich weiß. Der Variablenname ist total missverständlich aber so funktioniert es:

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;

jaenicke 12. Sep 2016 04:28

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.

dGeek 12. Sep 2016 09:54

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Zitat:

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.
Kannst du das bitte ekrlären?

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.

Luckie 12. Sep 2016 12:07

AW: FileExists/FileDate - Auslesen über Netzwerk langsam
 
Er meinst so was: http://michael-puff.de/Programmierun...rKlassen.shtml


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:17 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