Guten Tag Programmiersprache: C++ (MFC) Programmierumgebung: Visual Studio 2019 OS: Win10 . Aktuell nutze ich FindFirstFile / FindNextFile um mit meinem Programm Ordner zu durchsuchen um diese Daten weiterzuverarbeiten. Ich habe jetzt aber den Fall, dass ich zyklisch ein Netzwerklaufwerk mit über 30K Dateien durchsuchen soll. Dieses ist leider über ein extrem langsames Netzwerk eingebunden. Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. Gibt es einen Weg, die Dateien vor der Suche nach Datum zu sortieren bzw. die Suche auf einen gewissen Datumsbereich einzuschränken um die Suche zu beschleunigen? Denn so kann ich das Programm nur über das Wochenende laufen lassen ohne Probleme zu bekommen(Zu hohe Auslastung des Netzwerkes, Dateien werden während der Suche geändert,...).
> Ich habe jetzt aber den Fall, dass ich zyklisch ein Netzwerklaufwerk mit > über 30K Dateien durchsuchen soll. Das alleine ist schon ein nicht optimales Design. > Dieses ist leider über ein extrem langsames Netzwerk eingebunden. Das setzt dann dem Fass der Gemütlichkeit die Krone auf. Aber wie üblich lässt sich das Design nicht ändern und die Anbindung nicht verbessern stimmst ? Ist das Netzwerklaufwerk denn die Ganze Zeit verbunden ? Wenn nicht, ändern. ggf.mit der IT sprechen das auf dem Client die Indexierung (Auto Generierung von Vorschaubildern, Aufnahme in die den such Index usw. abgeschaltet wird. > Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. würde gefühlt das hier einsetzen: https://en.cppreference.com/w/cpp/filesystem/directory_iterator https://en.cppreference.com/w/cpp/filesystem/last_write_time > Denn so kann ich das Programm nur über das Wochenende laufen lassen ohne > Probleme zu bekommen(Zu hohe Auslastung des Netzwerkes, Dateien werden > während der Suche geändert,...). Das widerspricht sich mit "benötige ist nur Dateiname & Änderungsdatum" ein Directory Abruf bei 30k Files mit 10-14 Zeichen plus Datum sind 3-5MB Traffic.
Marc D. schrieb: >> Ich habe jetzt aber den Fall, dass ich zyklisch ein Netzwerklaufwerk mit >> über 30K Dateien durchsuchen soll. > Das alleine ist schon ein nicht optimales Design. > >> Dieses ist leider über ein extrem langsames Netzwerk eingebunden. > Das setzt dann dem Fass der Gemütlichkeit die Krone auf. > > Aber wie üblich lässt sich das Design nicht ändern und > die Anbindung nicht verbessern stimmst ? Leider ist dem so. Denn nur für mich, nur für diese eine Aufgabe wird leider nicht im großen Stil umgegraben & neue Kabel im Boden versteckt. Marc D. schrieb: > Ist das Netzwerklaufwerk denn die Ganze Zeit verbunden ? > Wenn nicht, ändern. ggf.mit der IT sprechen das auf dem Client > die Indexierung (Auto Generierung von Vorschaubildern, Aufnahme in die > den such Index usw. abgeschaltet wird. Auf der IT Seite wurde schon alles gemacht was möglich ist. Und ja. Das Netzwerklaufwerk ist dauern verfügbar. Marc D. schrieb: > >> Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. > > würde gefühlt das hier einsetzen: > https://en.cppreference.com/w/cpp/filesystem/directory_iterator > https://en.cppreference.com/w/cpp/filesystem/last_write_time > >> Denn so kann ich das Programm nur über das Wochenende laufen lassen ohne >> Probleme zu bekommen(Zu hohe Auslastung des Netzwerkes, Dateien werden >> während der Suche geändert,...). > > Das widerspricht sich mit "benötige ist nur Dateiname & Änderungsdatum" > ein Directory Abruf bei 30k Files mit 10-14 Zeichen plus Datum sind > 3-5MB Traffic. Der Traffic alleine ist nicht das Problem. Das Problem ist eher das andauernde Frage-Antwortspiel. Denn aktuell müssen erst alle Dateien des gesuchten Dateityps ermittelt und erst danach anhand des gesuchten Datumbereichs aussortiert werden. Und genau der Vorgang des Dateiname ermitteln, Dateidatum ermitteln & Verwerfen ist dass was aktuell den Großteil der Zeit beansprucht. Desswegen war die Frage ob man das Suchergebnis schon vor der Suche eingeschränkt werden kann um den Suchvorgang zu beschleunigen. Das Einzige was mir sonst noch einfällt ist kontinuierlich, langsam suche und dann zyklisch einen Report ausgebe.
Wenn dieses Netzlaufwerk auf irgendeinen Server liegt: Auf dem Server ein Script laufen lassen, der auf irgendeinem Port nach Deinen Client lauscht und bei Anforderung besagte Dateien sucht und die gesuchten Daten in eine Datei schreibt, die Du dann vom Client aus ausliest.
Abhängig von der Art des Netzlaufwerks/Betriebssystems das das Netzlaufwerk zur Verfügung stellt (SMB3?), geht auch https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstchangenotificationa
Bernhard schrieb: > Marc D. schrieb: >> Aber wie üblich lässt sich das Design nicht ändern und >> die Anbindung nicht verbessern stimmst ? > Leider ist dem so. > Denn nur für mich, nur für diese eine Aufgabe wird leider nicht im > großen Stil umgegraben & neue Kabel im Boden versteckt. Es gibt VIELE Möglichkeiten das Professionell zu lösen. Wenn die Infrastruktur sich nicht änder lässt kann man z.B die Auswertung auf der gleichen Maschine vorbereiten (locale File API, change event, stellt dir eine liste mit Änderungen bereit die klein und schnell ist). Oder auf einen "Service Server" der nebenstehend und besser angebunden ist. Grob von Gefühl würde ich sagen das eine wie auch immer geartet Auswertung und Verarbeitung auch nicht auf einen Client. Woanders würden Köpfe rollen wenn sie mitbekommen das Firmen Kritische Reporte auf dem PC bei Hannes unter dem Tisch durchgeführt werden.Aber das kann ich bei dir natürlich nicht sehen ob es so ist. > Und ja. Das Netzwerklaufwerk ist dauern verfügbar. Verfügbar ist ungleich verbunden in meinen Sprachgebrauch. > Der Traffic alleine ist nicht das Problem. Das Problem ist eher das > andauernde Frage-Antwortspiel. > Denn aktuell müssen erst alle Dateien des gesuchten Dateityps ermittelt > und erst danach anhand des gesuchten Datumbereichs aussortiert werden. > Und genau der Vorgang des Dateiname ermitteln, Dateidatum ermitteln & > Verwerfen ist dass was aktuell den Großteil der Zeit beansprucht. > Deswegen war die Frage ob man das Suchergebnis schon vor der Suche > eingeschränkt werden kann um den Suchvorgang zu beschleunigen. > Das Einzige was mir sonst noch einfällt ist kontinuierlich, langsam > suche und dann zyklisch einen Report ausgebe. Was genau machst du da ? Was genau dauert so lange ? Von Gefühl holst du dir einen File + Datum schaust ob du es gebrauchen kannst und machst dann weiter ? Üblicherweise zieht man sich die informationellen in ein Array und wertet dann dieses aus. Das Ergebnis wird dann benutzt und ggf. mit den Dateien zu arbeiten (was auch immer). Das ist nichts an Netzwerklast und ja klar https://docs.microsoft.com/windows-server/administration/windows-commands/forfiles forfiles macht nicht anderes und gerne genommen in batch Files. Dann kannst du auf dem Server laufen lassen um dir ggf. ein "hier nun drann arbeiten" liste zu erstellen.
Andreas B. schrieb: > Wenn dieses Netzlaufwerk auf irgendeinen Server liegt: > Auf dem Server ein Script laufen lassen, der auf irgendeinem Port nach > Deinen Client lauscht und bei Anforderung besagte Dateien sucht und die > gesuchten Daten in eine Datei schreibt, die Du dann vom Client aus > ausliest. Leider kann alles nur Clientseitig erledigt werden. Serverseitig habe ich leider keinen Zugriff. Tassilo H. schrieb: > Abhängig von der Art des Netzlaufwerks/Betriebssystems das das > Netzlaufwerk zur Verfügung stellt (SMB3?), geht auch > > https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstchangenotificationa Danke für den Tipp. Ich werde mir das anschauen sobald ich etwas Luft habe. (Das ist ein "mach das bitte mal so nebenbei" Projekt) Marc D. schrieb: > Grob von Gefühl würde ich sagen das eine wie auch immer > geartet Auswertung > und Verarbeitung auch nicht auf einen Client. Woanders würden Köpfe > rollen > wenn sie mitbekommen das Firmen Kritische Reporte auf dem PC bei Hannes > unter dem > Tisch durchgeführt werden.Aber das kann ich bei dir natürlich nicht > sehen ob es so ist. > > . > . > . > > Was genau machst du da ? Was genau dauert so lange ? > Von Gefühl holst du dir einen File + Datum schaust ob du es gebrauchen > kannst > und machst dann weiter ? Üblicherweise zieht man sich die > informationellen Wir bekommen hier Domumente (PDF) in einem Ordner gesammelt zur Verfügung gestellt und sollen dann sobald sich da etwas ändert diese Änderungen in unser System übernehmen. Die Änderungen können dabei durch eine neue Versionsnummer im Dateinamen, ein neues Änderungsdatum oder gelegentlich auch eine andere Dateigröße erkennbar sein. (Je nachdem wie viel Aufwand beim Schummeln betrieben wird.) Das Ganze ist also nichts anderes als eine Vergleichstabelle über die man Bescheid bekommt, sobald etwas geändert wird. Klingt dämlich, ist es auch. Ein ordentliches Änderungsbenachrichtigungssystem zu dieser eigenständig/unabhängig arbeitenden Sparte ist in Arbeit, wird aber noch mehr oder wenig lange dauern bis es umgesetzt wird.(Wenn überhaupt.) Also versuchen wir(ich) mit möglichst vertretbarem Aufwand der Angelegenheit Herr zu werden.
Bernhard schrieb: > Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. Dann setze doch einfach auf dem Server einen CronJob auf, der Dir jede Nacht das Verzeichnis in eine Textdatei schreibt. Die kannst Du dann in aller Ruhe sortieren.
Peter D. schrieb: > Bernhard schrieb: >> Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. > > Dann setze doch einfach auf dem Server einen CronJob auf, der Dir jede > Nacht das Verzeichnis in eine Textdatei schreibt. Die kannst Du dann in > aller Ruhe sortieren. Können vor lauter lachen. Leider habe ich auf den Server keinen Zugriff. Und es wird auch von der Gegenseite nichts gemacht, da ja ein Projekt zur ordentlichen Informationsübergabe in Arbeit ist. (Welches jetzt bald reif zur Einschulung ist.) Desswegen will ich jetzt zumindest das Provisorium soweit optimieren dass es bis zum Arbeitsbeginn fertig wird wenn ich das Ganze bei Arbeitsschluss starte.
Bernhard schrieb: > Leider habe ich auf den Server keinen Zugriff. Das ist kein technisches Problem, sondern ein Managementproblem. Die Lösung ist nunmal, das gleich serverseitig zu machen. Wenn diejenigen, die den Server verwalten, das nicht zulassen wollen: Eskalation ans Management. Bis dahin gibt's halt nur wöchentlich Reports.
Bernhard schrieb: > Deswegen will ich jetzt zumindest das Provisorium soweit optimieren > dass es bis zum Arbeitsbeginn fertig wird wenn ich das Ganze bei > Arbeitsschluss starte. Mein persönlicher Rat: lass es. Wenn es daran scheitert ein kleines Script auf dem Server laufen zu lassen, dann ist das wohl ein Thema welches niemanden interessiert. Da solltest auch du sagen "hier verschwende ich nicht meine wertvolle Zeit". Ich selbst bin auch jemand, den solche Sachen persönlich stören. Aber hier Zeit zu versenken bringt dich - vermute ich - weder beruflich noch persönlich weiter. Falls das Thema doch jemanden interessiert, dann Druck machen, dass es ordentlich gemacht wird (ich meine es geht um ein kleines Script o.ä.). Macht auch einen besseren Eindruck als ewig im Kämmerlein Workarounds zu basteln.
Wenn du Glueck hast, geht FindFirstChangeNotificationA. Falls nicht, wuerde ich auch dazu raten, das Unterfangen ohne Serverzugriff aufzugeben und an's Management weiterzureichen.
:
Bearbeitet durch User
Peter D. schrieb: > Bernhard schrieb: >> Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. > > Dann setze doch einfach auf dem Server einen CronJob auf, der Dir jede > Nacht das Verzeichnis in eine Textdatei schreibt. Die kannst Du dann in > aller Ruhe sortieren. Das ist nun mal die Lösung deiner Probleme, der Server muss die Dateiänderungen in geeigneter weise Dokumentieren. Wen er das nicht macht und du da nichts Installieren kannst/darfst ist das Problem nicht lösbar und du solltest nicht deine Zeit verschwenden. Vielleicht könnte man aber die Änderungen aus den Backupsteam des Server ableiten, sobald der Server sein Backup macht. Aber auch das Braucht Lösungswillen beim Serverbetreiber und ist wahrscheinlich auch Komplexer und schwerer als der Cronjob. Außerdem wäre das auch nicht sobald sich was ändert sondern, nach dem nächsten Backup. Bernhard schrieb: > Können vor lauter lachen. > > Leider habe ich auf den Server keinen Zugriff. > Und es wird auch von der Gegenseite nichts gemacht, da ja ein Projekt > zur ordentlichen Informationsübergabe in Arbeit ist. > (Welches jetzt bald reif zur Einschulung ist.) Bernhard schrieb: > Auf der IT Seite wurde schon alles gemacht was möglich ist. > Und ja. Das Netzwerklaufwerk ist dauern verfügbar. Klingt für mich nicht so, als würde alles gemacht, was möglich ist.
Wieso kann man nicht das A(rchiv)-Attribut abfragen? Oder mit RoboCopy (hieß damals das Windows Synctool) auswerten? Rsync ist auch sehr mächtig. Ist Windows schon so weit am Zerfall und der Rückbildung?
Bernhard schrieb: > Aktuell nutze ich FindFirstFile / FindNextFile um mit meinem Programm > Ordner zu durchsuchen um diese Daten weiterzuverarbeiten. > Ich habe jetzt aber den Fall, dass ich zyklisch ein Netzwerklaufwerk mit > über 30K Dateien durchsuchen soll. > Dieses ist leider über ein extrem langsames Netzwerk eingebunden. > > Was ich von diesen Dateien benötige ist nur Dateiname & Änderungsdatum. > > Gibt es einen Weg, die Dateien vor der Suche nach Datum zu sortieren > bzw. die Suche auf einen gewissen Datumsbereich einzuschränken um die > Suche zu beschleunigen? Nein. Deswegen wird sich die "Suche" auch nicht beschleunigen lassen. Da sollte man dann mal drüber nachdenken, ob eine "Suche" eigentlich grundsätzlich das richtige Konzept ist. Wenn die Verbindung zwar langsam, aber immerhin dauerhaft verfügbar ist, gäbe es auch andere Möglichkeiten.
Bernhard schrieb: > Dieses ist leider über ein extrem langsames Netzwerk eingebunden. Nun ja. Du wirst primär ein Latenzproblem, und kein Bandbreitenproblem haben. 30.000 Dateien sind sehr wenig. Gegen Latenzen gibt es ein Mittel: Nebenläufigkeit. D.h. Du baust eine Workqueue und ein Threadpool. Damit scannst Du, z.B. mit 100 Threads, parallel. Jeder OS-Aufruf, der eine Serveranfrage verursacht, wird parallelisiert und durch die Workqueue geprügelt. Du musst natürlich etwas Organisation betreiben, damit Du nicht zu viele Ressourcen, z.B. Directory-Handles gleichzeitig offen hast. Aber das ist nicht viel Aufwand. Gibt denkbar viele Ansätze dafür. Z.b. unterschiedliche Queues etc. Ziel der Übung ist es, die Bandbreite der Verbindung zu sättigen.
Experte schrieb: > D.h. Du baust eine Workqueue und ein Threadpool. Damit scannst Du, z.B. > mit 100 Threads, parallel. Für etwas, das nativ auf dem Server mit nur einem Thread in deutlich unter einer Sekunde durch wäre, sofern man eine SSD voraussetzen darf.
FindFirstFile / FindNextFile sind nicht sehr effektiv, da sie immer die gesammte Directory Info neu durchsuchen (und übers Netz neu übertragen). Es gibt eine Low Level Api, auf die FindFirstFile aufbaut, und die effizienter ist (Name habe ich leider vergessen). Das wäre eventuell das, was du brauchst. Oder, du verwendest die .NET FileSystemWatcher, bzw. das darunterliegende Win32 Api FindFirstChangeNotification. Das setzt bei einem Server SMB 2.0 voraus.
Ich habe mich noch mal schlau gemacht, die Low Level Api ist NTQueryDirectoryFile. Es geht aber auch einfacher mit FindFirstFileEx, wenn du das Flag FIND_FIRST_EX_LARGE_FETCH in FindExInfoBasic setzt.
Wenn es um Performance geht, ist es gut, wenn man zumindest eine Referenz hat, die vorlegt, was es schon mal gibt. (z.B. https://github.com/rchui/perg ) Ausprobieren bzw. Referenzen zusammenstellen, müsste man aber selber - wie auch das Management beim Setup evaluieren. ;)
Ich hab mal im CMD-Fenster ein DIR /S auf ein Netzlaufwerk losgelassen und in eine lokale Datei geschrieben. Das hat nur wenige Minuten gedauert. 101417 Datei(en), 22.463.348.539 Bytes 34643 Verzeichnis(se)
Natuerlich ist das Problem loesbar, wenn auch nicht zu jedermans Zufriedenheit. Falls es denn sein muss, einen Prozess auf dem Clientrechner laufen lassen, welcher konstant das Directory scannt. Allenfalls einen Binaerbaum nachfuehrt. Netzwerkbandbreite ist nicht so das Problem nehme ich an. Auf dem Server ist das Directory ja gecäscht, beschaeftigt die Disk daher minimal. Der eigene Prozess entkoppelt die auswertung des Scans vom Scan selbst, sonst waere die Auswertung blockiert bis der Scan fertig ist. Meine Loesung : voll saugen lassen. Was das Netzwerk und die Verbindungsprioritaet hergibt.
:
Bearbeitet durch User
Ich hab das Problem jetzt übrigens auf die einfache Art gelöst. Ich bekomme täglich eine Kopie des Backup-Logs von dem Laufwerk vom Admin geschickt. Das ist einfacher & angenehmer zu verwenden
Kommt darauf an, wie oft sich die Dateien bzw. deren Bestand ändern und wie schnell man das bemerken muss. Ich habe ein vergleichbares Problem damit gelöst, dass ich den gesamten Datenbestand in einem NAS-Share (ca. 40.000 Files in ca. 10.000 Verzeichnissen) regelmäßig rekursiv durchsuche und Dateipfad, Dateiname, Erstellungs- und Modifikations-Zeitstempel, die Dateigröße und einen aus diesen Daten erstellten MD5-Hash in einer SQL-Datenbank ablege bzw. damit vergleiche. Zusätzlich (es handelt sich um eine Art Bildarchiv im PDF-Format) wird von er ersten Seite ein ca. 400 x 600 Pixel großes Vorschaubild in base64-codiertes PNG gerendert und in der DB abgelegt. Das ganze funktioniert wie ein differenzielles Backup: Beim ersten Durchlauf dauert das ca. 120 Minuten, weil jeder Datensatz neu angelegt werden muss. Bei jedem weiteren Zyklus wird (bis auf eine verknüpfte Zyklus-ID in eigener, indizierter Tabelle) auf das Schreiben in die Datenbank verzichtet, wenn sich der Hash nicht geändert hat. Datensätze, deren Zyklus-ID nicht dem aktuellen Zyklus entspricht, werden gelöscht, weil offenbar die zugehörige Datei oder das Verzeichnis gelöscht wurde. So ein Durchlauf dauert dann nur noch ca. 3...4 Minuten, sofern sich nicht viel geändert hat. D.h. Veränderungen in dem Dateibestand werden also spätestens nach ca. 4 Minuten in der Datenbank aktualisiert sein. Das reine Suchen in den Bestandsdaten dauert dagegen nur Sekundenbruchteile.
:
Bearbeitet durch User
Ich weiß nicht, ob die Frage noch aktuell ist, aber hier finden sich Hinweise, wie die FileSystemWatcher Klasse in .Net implementiert ist - ReadDirectoryChangesW() sollte in C++ aufrufbar sein: https://stackoverflow.com/questions/627068/how-does-filesystemwatcher-work-on-another-computers-directory
Diese Change-Events kommen aus dem NTFS-System und werden nur über unterschiedliche APIs "noch oben" durchgereicht. Das funzt wahrscheinlich nur lokal, oder man installiet einen eigenen Dienst, der entsprechende Nachrichten übers Netz versendet. Und falls das alles kein Problem sein sollte bzw. es das schon gibt, dann greift es doch nur bei neuen Veränderungen, was ist mit den bereits existierenden Dateien?
Frank E. schrieb: > Das funzt > wahrscheinlich nur lokal, oder man installiet einen eigenen Dienst, der > entsprechende Nachrichten übers Netz versendet. Nein, auch im Netzwerk (ween der Server das unterstützt). Siehe [https://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw_19.html Understanding ReadDirectoryChangesW - Part 2] > > Und falls das alles kein Problem sein sollte bzw. es das schon gibt, > dann greift es doch nur bei neuen Veränderungen, was ist mit den bereits > existierenden Dateien? Änderungen an bestehenden Dateien werden ebenfalls ermittelt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.