Problém při zachytávání změny souboru   zodpovězená otázka

VB.NET

Narazil jsem na jeden drobný problém. Potřebuji zachytit změnu jednoho konkrétního souboru na jednom konkrétním místě. Zjednodušená konstrukce mého řešení vypadá asi takto:

Public Class Form1
    Private WithEvents zmenaSouboru As New System.IO.FileSystemWatcher

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        zmenaSouboru.Path = "c:\"
        zmenaSouboru.IncludeSubdirectories = False
        zmenaSouboru.Filter = "test.xml"
        zmenaSouboru.EnableRaisingEvents = True
    End Sub

    Private Sub zmenenSoubor(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles zmenaSouboru.Changed
        MsgBox("soubor změněn")
    End Sub
End Class

Vše funguje OK s jednou menší kosmetickou vadou.

Nevěděl by někdo z přítomných, proč se mi událost změny souboru vyvolá vždy 2x za sebou? Vždy když změním hlídaný soubor, tak mi to vypíše mou mesáž, jenže po jejím odklepnutí ji pro velký úspěch ještě jednou zopakuje??? (zatím jsem s tím nepracoval, takže pravděpodobně dělám někde nějakou triviální chybu).

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To je opravdu velmi zvláštní, nikdy se mi to nestalo. Jediné, co mě napadá, je zapsat si poslední čas a název změněného souboru a pokud je soubor změněn znovu do 1 sekundy, tak událost neprovádět. Ale rozhodně to není čisté řešení, spíš nouzovka.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Tak jsem tu Vaši "nouzovku" aplikoval:

Private Sub zmenenSoubor(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles zmenaSouboru.Changed
    Static Dim cas As DateTime
    If Now.Subtract(cas).TotalSeconds > 1 Then MsgBox(e.FullPath & " - " & e.ChangeType.ToString & " - " & e.Name)
    cas = Now
End Sub

Sice to funguje a pro můj účel je to použitelné, ale ještě tady ten dotaz nechám chvíli viset, kdyby náhodou někdo věděl, kde dělám chybu (nebo že by se sekli páni v Redmondu, když ani Vy si nevíte rady? :-))

Ale i tak dík.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

mam pocit ze to sa udeje preto, lebo sa vrati viac eventov ako jeden, kedze nie je definovany NotifyFilter. Je celkom mozne ze sa vratia napriklad eventy kvoli LastAccess, aj kvoli LastWrite zaroven....doporucujem skusit toto pridat:

zmenaSouboru.NotifyFilter = (NotifyFilters.LastAccess)

mozne enumeratory su aj

Attributes - The attributes of the file or folder.

CreationTime - The time the file or folder was created.

DirectoryName - The name of the directory.

FileName - The name of the file.

LastAccess - The date the file or folder was last opened.

LastWrite - The date the file or folder last had anything written to it.

Security - The security settings of the file or folder.

Size - The size of the file or folder

dufam ze to pomoze.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Díky - zkusím to co nejdříve. Původně jsem chtěl ještě zkusit hlídat událost posledního zápisu (evidentně to má stejný význam, protože událost "changed" se vyvolá i když soubor nezměním a jen ho opětovně uložím), jen jsem se k tomu ještě nedostal.

V mém případě (s událostí changed) jsem ale zkoušel ještě to, že jsem si do msgboxu nechal vypsat odesílatele události i popis události jako takové a v prvním i druhém eventu se vše zcela shodovalo, takže jsou vyvolávány 2x po sobě úplně stejné události. A předpokládám, pokud nenastavím notifyFiltr, tak by to nemělo hlídat žádný z eventů (ale jak říkám, ještě jsem to nezkoušel), a i kdyby jo, pak by mi to mělo tento "jiný" event vypsat, nebo ne?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak jsem si hrál s těma notify filtrama a zdá se, že do toho začínám pomalinku nahlížet. Přiznám se, že původně jsem si myslel, že jde o dvě zcela samostatné kategorie toho, co všechno chci hlídat. Ale až po menším bádání jsem dospěl k závěru, že se jedná o záležitosti spojené a to tak, že ve filtru si řeknu co konkrétního chsi v adresáři monitorovat (atributy souborů, názvy souborů, velikost souborů, atd..), jenomže pak u těchto jednotlivostí rozhodnu, jakou jejich událost vůbec budu zachytávat (změnu, vytvoření, zrušení,...) No a toto mne původně dost zmátlo, protože u většiny atributů je logická pouze změna (jak chcete "vytvořit" nebo "smazat" třeba čas vytvoření souboru - ten je přece svázán s jeho existencí a já jej mohu pouze změnit-kdo nyní namítne, že vytvořením souboru "vytvořím" i čas jeho vytvoření, což by ve svém důsledku mohlo být i logické, tak bohužel, takovouto událost mi "Created" aplikované na čas vytvoření souboru nezachytí!?)

No ale k mému problému.

Zkusil jsem tedy laborovat s různými možnostmi a dospěl jsem ke konečnému "TÉMĚŘ" funkčnímu řešení:

Public Class Form1
    Private WithEvents zmenaSouboru As New System.IO.FileSystemWatcher

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        zmenaSouboru.Path = "c:\"
        zmenaSouboru.IncludeSubdirectories = False
        zmenaSouboru.Filter = "test.xml"
        zmenaSouboru.NotifyFilter = IO.NotifyFilters.LastAccess
        zmenaSouboru.EnableRaisingEvents = True
    End Sub

    Private Sub zmenenSoubor(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles zmenaSouboru.Changed
        MsgBox(e.FullPath & " - " & e.ChangeType.ToString & " - " & e.Name)
    End Sub

End Class

To téměř je tam kvůli jedné chybičce, kterou jsem objevil, a totiž, že se mi nevyvolá událost v případě, že otevřu totálně prázdný soubor a opět jako totálně prázdný jej uložím??

Jinak pokud v něm je cokoliv, byť i mezera, mohu ukládat a ukládat a vyvolá se mi 1X událost správně, a to i v případě, že jsem v souboru něco měl, smažu obsah a soubor nyní již jako prázdný uložím. Toto pro mou požadovanou funkčnost PLNĚ postačuje, protože můj soubor nebude nikdy prázdný a i kdyby, je spíše přínosem, že se nebude spouštět analýza nezměněného prázdného souboru, ale stejně to považuji za dosti zvláštní chování. Mohl by mi to někdo vysvětlit, protože takto nejsem schopen predikovat funkcionalitu jakéhokoliv řešení, pokud si to neosahám).

Stejnou abnormalitou je, dle mého laického názoru, že pokud do filtru zadám:

zmenaSouboru.NotifyFilter = IO.NotifyFilters.LastWrite 

, což by dle mého byla i logická volba, pak dostanu stejný výsledek, jako když jsem původně filtr neměl vůbec nastavený, tedy zdvojené vyvolání události, přestože si myslím, že pokud soubor uložím, zapíše se pouze jedenkrát???

Pro svůj problém to již sice nepotřebuji, ale nevíte někdo, jak teda tato třída (FileSystemWatcher) vůbec funguje?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Nějak z toho nemuzu dostat velikost souboru. Potrebuji do proměnné načíst velikost konkrétního souboru na disku. Zmenu souboru resim takto:

Dim Dm As Date = IO.File.GetLastWriteTime(DBSoubor)

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Omlouvám se, ale nějak jsem Váš příspěvek nepochytil - jednak Vaším kódem nijak "neřešíte" změnu souboru - pouze načítáte do proměnné čas posledního uložení souboru, a k té velikosti, s tématem to nemá moc společného, ale velikost souboru zjistíte třeba:

dim velikost as Long = FileSystem.FileLen(path)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Neni se zac omlouvat, chyba na me strane. Fakt jsem nepochopil, ale dik za tip, to bude vončo. dik

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback