Überwachung eines Verzeichnisses für die Erstellung neuer Dateien ohne FileSystemWatcher

7

Ich muss einen Windows-Dienst erstellen, der einen bestimmten Ordner auf neue Dateien hin überwacht und sie verarbeitet und an einen anderen Ort verschiebt.

Ich begann mit FileSystemWatcher . Mein Chef mag FileSystemWatcher nicht und möchte, dass ich den Abruf unter Verwendung von Timer oder eines anderen Mechanismus als FileSystemWatcher verwende.

Wie können Sie die Verzeichnisverwaltung überwachen, ohne FileSystemWatcher mit .NET Framework zu verwenden?

    
Abbi 31.08.2010, 19:06
quelle

8 Antworten

6

Unter Verwendung von @ Petojs Antwort habe ich einen vollständigen Windows-Dienst hinzugefügt, der alle fünf Minuten nach neuen Dateien fragt. Es ist so eingeschränkt, dass nur ein Thread abfragt, die Verarbeitungszeit berücksichtigt und die Pause und das rechtzeitige Stoppen unterstützt. Es unterstützt auch das einfache Anhängen eines Debbuggers an system.start

%Vor%     
Conrad Frix 31.08.2010, 21:45
quelle
17

Tatsächlich ist die FileWatcher-Komponente aus meiner Erfahrung im Laufe der Jahre nicht zu 100% "stabil". Schieben Sie genügend Dateien in einen Ordner und Sie werden einige Ereignisse verlieren. Dies gilt insbesondere, wenn Sie eine Dateifreigabe überwachen, selbst wenn Sie die Puffergröße erhöhen.

Verwenden Sie FileWatcher also aus praktischen Gründen zusammen mit einem Timer, der einen Ordner nach Änderungen durchsucht, um die optimale Lösung zu finden.

Beispiele für die Erstellung von Timer-Code sollte reichlich vorhanden sein, wenn Sie es googlen. Wenn Sie beim Ausführen des Timers die letzte DateTime verfolgen, überprüfen Sie das Änderungsdatum jeder Datei und vergleichen Sie es mit dem Datum. Ziemlich einfache Logik.

Das Zeitgeberintervall hängt davon ab, wie dringend die Änderungen für Ihr System sind. Aber überprüfen Sie jede Minute sollte für viele Szenarien in Ordnung sein.

    
Mikael Svenson 31.08.2010 19:21
quelle
4

Verwenden Sie beim Programmstart Directory.GetFiles (Pfad), um die Liste der Dateien abzurufen.

Dann erstellen Sie einen Timer und in seinem abgelaufenen Ereignis Aufruf hasNewFiles:

%Vor%

Im aufrufenden Code haben Sie neue Dateien, wenn:

%Vor%

edit: wenn Sie eine linqy Lösung wollen:

%Vor%     
Steven Evers 31.08.2010 19:28
quelle
4

Sie könnten Directory.GetFiles() :

verwenden %Vor%

Beachten Sie, dass dies nur nach neuen Dateien und nicht nach geänderten Dateien sucht, wenn Sie FileInfo

benötigen     
Peter 31.08.2010 19:12
quelle
1

Ich würde fragen, warum nicht den FileSystemWatcher verwenden. Es registriert sich beim Betriebssystem und wird sofort benachrichtigt, wenn das Ereignis im Dateisystem beendet ist.

Wenn Sie wirklich abfragen müssen, erstellen Sie einfach einen System.Timers.Timer, erstellen Sie eine Methode zum Aufrufen und suchen Sie nach der Datei in dieser Methode.

    
davisoa 31.08.2010 19:10
quelle
1

Ja, Sie können einen Timer erstellen und einen Handler in das Elapsed-Ereignis einfügen, das eine DirectoryInfo-Klasse für das gerade angezeigte Verzeichnis instanziiert und entweder GetFiles () oder EnumerateFiles () aufruft. GetFiles () gibt ein FileInfo [] -Array zurück, während EnumerateFiles () ein "streaming" IEnumerable zurückgibt. EnumerateFiles () ist effizienter, wenn Sie erwarten, dass sich viele Dateien in diesem Ordner befinden, wenn Sie suchen. Sie können mit dem IEnumerable arbeiten, bevor die Methode alle FileInfos abgerufen hat, während GetFiles Sie warten lassen.

Warum dies möglicherweise besser als FileWatcher ist, hängt von der Architektur hinter den Kulissen ab. Nehmen wir zum Beispiel einen grundlegenden Workflow zum Extrahieren / Transformieren / Validieren / Laden. Erstens muss ein solcher Workflow möglicherweise teure Instanzen von Objekten erstellen (DB-Verbindungen, Instanzen einer Regel-Engine usw.). Dieser einmalige Overhead wird erheblich verringert, wenn der Workflow so strukturiert ist, dass alles, was ihm zur Verfügung steht, auf einmal bearbeitet werden kann. Zweitens würde FileWatcher erfordern, dass alles, was von den Ereignisprozeduren aufgerufen wird, wie dieser Workflow threadsicher ist, da viele Ereignisse gleichzeitig ausgeführt werden können, wenn Dateien ständig einfließen. Wenn dies nicht möglich ist, kann ein Timer sehr einfach konfiguriert werden um das System auf einen laufenden Workflow zu beschränken, indem Event-Handler ein thread-sicheres "Process Running" -Flag prüfen und einfach beenden, wenn ein anderes Handler-Thread es gesetzt und noch nicht beendet hat. Die Dateien in dem Ordner zu diesem Zeitpunkt werden bei der nächsten Ausführung des Timers aufgenommen, im Gegensatz zu FileWatcher. Wenn Sie den Handler beenden, geht die Information über das Vorhandensein dieser Datei verloren.

    
KeithS 31.08.2010 21:32
quelle
0

1) Klingt wie dein Chef ein Idiot ist 2) Sie müssen Funktionen wie Directory.GetFiles, File.GetLastAccessTime usw. verwenden und im Speicher behalten, um zu überprüfen, ob es sich geändert hat.

    
Wildhorn 31.08.2010 19:13
quelle
0

Es ist ein wenig merkwürdig, dass Sie FileSystemWatcher oder vermutlich keine der Win32-APIs verwenden können, die das gleiche tun, aber das ist an dieser Stelle irrelevant. Die Abrufmethode könnte so aussehen.

%Vor%     
Brian Gideon 31.08.2010 19:16
quelle

Tags und Links