Dateiinformation (sehr schnell) von SMB-Share lesen

  • Hallo,

    Ich muss aus einem SMB-Verzeichnis eine grosse Anzahl (>1000) von Dateien lesen. Genau genommendie Dateinamen und die Datumsinfo der Datei, keine Inhalte. Ich mache folgendes:

    1. Dateien mit _FileReadToArray einlesen

    2. Jede Datei im Array mit den Datumsinformationen (FileGetTime) versehen

    3. Das Array dann nach dem Datum sortieren

    4. Älteste Datei zurückgeben

    Punkt 1 geht recht schnell, Punkt 2 braucht viel Zeit und Punkt 3 geht auch wieder schnell. Kennt jemand eine Lösung, wie ich das beschleunigen kann?

    Das ist alles ziemlich zeitkritisch, da eine grosse Anzahl von Clients (>100) gleichzeitig auf den Server auf das gleiche Verzeichnis zugreift.

    Danke schon einmal....

    -ovik

    Die zugehörige Funktion sieht folgendermaßen aus:

  • For $iFile = 1 To $aFiles[0] Step 1
    Local $date = FileGetTime($SoureDirectory & $aFiles[$iFile], 0, 1)
    _ArrayAdd($aFileAndDate, $aFiles[$iFile] & '|' & $date)
    Next

    Vergrößere vor der Schleife das Array um die Anzahl an Indizes (ReDim) die dazu kommen, innerhalb der Schleife beschreibst du dann nur den Index.

    Das sollte das ganze (bei den entsprechenden Größen) ein wenig verschnellern.

  • Danke alpines und gute Idee, an die ich nicht gedacht habe (ReDim geht übrigens nicht, aber _ArrayColInsert does the trick...

    Hab das grad mal versucht und bringt praktisch nichts (bei 1000 Files 2.3 statt 2.4 Sekunden, mehrere Versuche...). Das Nadelöhr ist wohl das einsammeln der Datumsinformationen. Kann man das irgendwie beschleunigen. Leider zieht _FileListToArray diese Informationen nicht :(

  • Teste einmal diese Func:

    ungetestet , an den geänderten Zeilen habe ich Bemerkungen angehängt.

  • autoBert

    ist praktisch gleich wie die Version mit _ArrayCollinsert (uns musste noch die $aFiles in $FileAndDate ändern, war ja ungetestet...).

    Die Arraysort-Funktion ist sehr schnell. Mir scheint das Ermitteln der FileGetTime das Problem zu sein.... Geht da noch was :-)??


    Mittelwerte für 10 Durchläufe bei knapp 1000 Dateien:

    Version0: 2.2588356952025

    Version1: 1.83035228628271

    Version2: 1.82812738483125


    3 Versionen der Funktion
  • Das ist alles ziemlich zeitkritisch, da eine grosse Anzahl von Clients (>100) gleichzeitig auf den Server auf das gleiche Verzeichnis zugreift.

    Anstatt alle Clients auf das Verzeichnis zugreifen zu lassen, würde ich einen speziellen Prozess dafür starten, der diese Arbeit erledigt und die gewünschten Informationen dann auf Anfrage via UDP/TCP an die Clients sendet.

    Wenn auf dem Server Windows installiert ist und du dort den speziellen Prozess starten kannst/darfst, könntest du das Verzeichnis mit _WinAPI_ShellChangeNotify überwachen, was den Vorteil hätte, dass du benachrichtigt wirst, wenn sich darin etwas verändert hat.

  • Teste mal ob es nicht wesentlich schneller geht auf Autoit Funktionen zu verzichten und stattdessen Windows Boardmittel zu nutzen. Soweit ich dich verstehe willst du lediglich den Dateinamen der ältesten TXT-Datei im Verzeichnis (modify date). Folgender DOS Befehl liefert dir in der ersten Zeile die gewünschte (älteste) Datei.

    Code
    dir *.txt /A-D /B /OD /TW

    Du sparst dir damit eigentlich alles. Du musst nur noch via Autoit den stdout Stream mitlesen und mit den Stringfunktionen die erste Zeile parsen. Theoretisch kannst du nach der ersten Zeile sogar das stdout lesen abbrechen und die Schleife verlassen.

    Ob der DOS Befehl "dir" jedoch auf deinem Netzlaufwerk nicht die selben Performanceprobleme hat müsstest du testen. Falls das hier auch der Fall ist liegt das Problem eher am Netzwerk oder NAS.

  • Teste mal ob es nicht wesentlich schneller geht auf Autoit Funktionen zu verzichten und stattdessen Windows Boardmittel zu nutzen.

    Lustig, das habe ich auch gerade probiert !

    Ovik :

    Falls es mit CMD DIR funktioniert, dann sieht der Code z.B. so aus :

    EDIT : Quellcode neu :

    Getestet lokal mit 3000 Dateien im Unterverzeichnis \Files

    Zeitdauer : 76.494 Millisekunden


    EDIT : Achtung, da scheint noch eine Macke drin zu sein - checke ich gerade !

    EDIT 2 : Ok, so geht es - Zeitdauer : ca. 300 Millisekunden

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

    2 Mal editiert, zuletzt von Musashi (21. Februar 2019 um 23:04)

  • Der Server ist ein Synology NAS

    Ok, kein Windows... aber einen speziellen Prozess kannst du ja trotzdem dafür starten... das bringt sicher den meisten Zeitgewinn!

    dir *.txt /A-D /B /OD /TW

    Das (/T) wird mit seiner Synology NAS nicht funktionieren, weil er dort mit Sicherheit kein NTFS hat.

    Eine Alternative wäre, ein Bash-Script auf dem Synology NAS via Crontab auszuführen, dass die gewünschten Ergebnisse in eine Datei speichert und die Clients diese dann auswerten. Ich kenne mich ein wenig mit Linux aus (15+ Jahre Debian) und könnte dir dabei helfen.

    Falls es mit CMD DIR funktioniert, dann sieht der Code z.B. so aus :

    Hier eine verkürzte Version von Musashi

  • Hier eine verkürzte Version von Musashi

    Ich war gerade selbst am Kürzen, aber das kann ich mir, Dank Dir, jetzt sparen. Besser wird es nicht ;).

    Eine Alternative wäre, ein Bash-Script auf dem Synology NAS via Crontab auszuführen, dass die gewünschten Ergebnisse in eine Datei speichert und die Clients diese dann auswerten. Ich kenne mich ein wenig mit Linux aus (15+ Jahre Debian) und könnte dir dabei helfen.

    Das scheint mir auch die sauberste Lösung zu sein !

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Das (/T) wird mit seiner Synology NAS nicht funktionieren, weil er dort mit Sicherheit kein NTFS hat.

    Also zumindestens unser QNAP NAS verwendet/unterstützt NTFS. Der Hinweis ist aber natürlich berechtigt.

    Das scheint mir auch die sauberste Lösung zu sein !

    Ob das die sauberste Lösung ist sei mal dahingestellt. Ich würde mir anschauen ob das ganze Vorgehen Sinn macht. Warum 100 Clients zeitgleich auf das NAS zugreifen und die älteste Datei ermitteln müssen ist mir nachwievor unklar.

    Wie kommen die Dateien denn dahin?

    Was steht da drin?

    Was machen die Clients mit der Information?

    Was soll eigentlich am Ende erreicht werden?

    Das sind die Fragen die man sich stellen sollte um eine saubere Lösung zu finden.

  • Da hast Du natürlich recht !

    Meine Aussage "... die sauberste Lösung" bezog sich auf die Varianten :

    A: -> 100 Clients suchen sich die älteste Datei selbst

    B: -> der Server ermittelt diese Information und stellt sie den Clients zur Verfügung

    und hätte besser "... die sauberere Lösung" (hier B:) lauten müssen.

    Um zu einer sauberen Lösung zu gelangen, sollte die Vorgehensweise grundsätzlich auf den Prüfstand gestellt werden.

    Sofern der Zugriff technisch funktioniert, hat Ovik mit dem CMD/DIR Ansatz jetzt zumindest aber eine bordeigene Alternative.

    Da kenne ich mich auch zu wenig aus, würde also lieber was an meinem Script anpassen....

    Ob es klappt, wird er uns sicher mitteilen.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."