monitorování změn v adresářové struktuře rubrika: Programování: .Net
Potřeboval bych vyřešit následující problém:
- aplikace, která bude sledovat změny ve specifické adresářové podstruktuře (vytvoření, smazání, přejmenování, přesun)
- měla by sledovat i přístup, tedy otevření souboru, aktualizace souboru
- změny se budou posílat na http rozhraní
- musí být ošetřeny stavy, kdy nebude spuštěná aplikace, výpadek spojení nebo jiné selhání monitoringu (aplikace tedy musí umět poslat kompletní otisk struktury)
- je klíčové, aby změny byly vidět v reálném čase
Jediné řešení, které mě napadlo, je oprášit .NET a pomocí FileSystemWatcher zachytávat změny. Problémy jsou přesuny adresářů. Dále si aplikace na straně http rozhraní musí ukládat svůj kompletní stav struktury a ten porovnávat s novým stavem - porovnáním dvou stromů - je to nezbytné právě kvůli možným výpadkům.
Implementovat to řešení na straně http rozhraní nelze - stroje nejsou na stejných místech a i kdyby, tak je to windows x linux a zachytávat změny na sambě asi též nereálné.
Napadá vás nějaké elegantnější hotové řešení?
Toto nelze spolehlive realizovat na urovni aplikacniho Windows API, predevsim sledovani otevreni souboru a pozadavek na realny cas notifikaci techto zmen. Bylo by treba napsal kernel filter driver a z neho to pak prenaset do "user" aplikacniho modu (pomoci overlapped DeviceIoControl volani). Takhle to dela Process Monitor, podrobnosti zde.
Trida FileSystemWatcher je patrne zalozena na ReadDirectoryChangesW. Napriklad notifikace FILE_NOTIFY_CHANGE_LAST_ACCESS muze byt zakazana z duvodu lepsiho vykonu NTFS.
K cemu to ma cele slouzit ?
Komentáře
-
dzejkob
:
Pokud je zakázáno, tak se povolí. Kernel filter driver je už moc přehnané. Měl by (doufám) stačit filesystemwatcher. Je mi jasné, že to nemusí být 100% - proto tam musí být nějaká zadní vrátka.
—
12.6.2013
-
Petr Voneš
:
Kdyz to nemusi byt zcela aktualni (realtime), pak asi opravdu staci FileSystemWatcher s tim, ze kdyz je delsi dobu "idle", vyplati se udelat scan cele adresarove struktury (nemusi byt najednou, treba po skupinach adresaru, idealne se na to hodi TPL). Ty notifikace pres API nejsou z principu zcela spolehlive a nekdy se muze takova udalost pro dany soubor ztratit, pokud je hodne zmen najednou.
—
17.6.2013
-
Honza Břešťan
:
Spis nez TPL bych na to hodil Quartz.NET. Nechat udalosti, at se vystreluji, a k tomu jednou za nejaky interval pustit scan.
—
17.6.2013
-
dzejkob
:
No core část již mám hotovou. Obsahuje to dva watchery, jeden pro soubory, druhý pro adresáře (jinak nejde rozlišit u OnDelete zda šlo o adresář, nebo soubor). Je důležité, aby to mělo na druhé straně uloženou celou strukturu včetně UIDs (uid není definované implicitně, nicméně při prvním dotazu se vytvoří a uloží k souboru/složce natrvalo). Pak se kumulují události do zásobníku a pokud se 2 sekundy nic neděje, tak se dávkově pošlou na rozhraní (v okamžiku kdy se odesílá, tak se události opět kumulují). Je třeba ošetřit několik věcí - za prvé, pokud se soubor maže, tak to musí zjistit UID podle cesty co je uložené v databázi - pak pokud se zachytí dvě události smazání + vytvoření se stejným UID, tak se akce transformuje na přesun. Funguje to překvapivě velice dobře - umí to přesuny souborů, struktur, podstruktur, přejmenování atd. - watchery mají větší buffer size a dokáží zachytit hodně události. Syncrhonizace celých stromů ani není potřeba. Problém nastane pouze v případě, že by někdo kopíroval v jeden okamžik stovky souborů a složek - což se dít nebude.
—
18.6.2013
Pro zobrazení všech 4 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře