Artykuły

A A A
Drukuj Ekportuj do PDF
Opublikowane: 2004.03.03 15:03 | Jakub Gutkowski | Aktualizacja: 2010.01.21 2:04

Monitorowanie plików za pomocą VB.NET

Prosty sposób na monitorowanie plików/katalogów na dysku twardym

Za pomocą klasy FileSystemWatcher, można określić, kiedy i jaka zmiana zaszła w pojedynczym folderze, wszystkich folderach czy na plikach w nich zawartych (oczywiście, można nie oznacza robić, chociażby zapuszczenie FileSystemWatcher na dysku systemowym dałoby olbrzymią liczbę wywołań zdarzeń, w których ponad 98% nie interesowałoby potencjalnego użytkownika, a obsłużenie ich w kodzie nie należałoby to rzeczy, które „tygryski lubią najbardziej”).

Tabela 1 zawiera listę wszystkich zdarzeń obsługiwanych przez klasę FileSystemWatcher. Wynika z niej, że w kodzie aplikacji wykorzystującej komponent FileSystemWatcher, można uzyskiwać informację o utworzeniu, usunięciu, zmienieniu nazwy, czy zmodyfikowaniu (w dowolny sposób) plików/katalogów, co w cale nie oznacza, że aby użyć tej klasy należy obsłużyć każde zdarzenie. Równie dobrze można obsłużyć tylko jedno z nich, jak i wszystkie, wszystko zależy od programisty.

Zdarzenie generowane

Opis zdarzenia

Changed

Uruchamiane, gdy plikowi lub katalogowi zostanie zmieniona jedna z własności:

  • Praw dostępu

  • Rozmiaru

  • Data ostatniego zapisania

  • Data ostatniego dostępu

  • Atrybuty systemowe

Created

Uruchamiane za każdym razem, gdy zostanie utworzony plik lub folder.

Deleted

Uruchamiane za każdym razem, gdy zostanie usunięty plik lub folder.

Renamed

Uruchamiane za każdym razem, gdy zostanie zmieniona nazwa pliku lub folderu.

Tabela 1 Zdarzenia generowane przez FileSystemWatcher

Najlepiej zaobserwować sposób działania klasy FileSystemWatcher przez praktykę, w tym celu należy uruchomić Visual Studio .NET i utworzyć nowy projekt aplikacji windowsowej (tutaj wybór jest dowolny równie dobrze można korzystać z klasy FileSystemWatcher w C# jak i VB.NET). Następnie dodać do Form1 komponent Button i TextBox tak jak to pokazano na rysunku 1.

Rys. 1 Główne okno aplikacji

Następnie na Form1 należy dodać komponent FileSystemWatcher, który znajduje się w zakładce Components w ToolBoxie. Ze względu na to, że komponent jest niewidoczny, jego istnienie w aplikacji można zaobserwować w kodzie lub w oknie projektowania Form1 w dolnym pasku zwanym tray.

Kolejnym krokiem jest dodanie deklaracji używania/zaimportowania (w zależności od języka) przestrzeni nazw System.IO.

using System.IO;

Kod 1 Kod Dla C#

Imports System.IO

Kod 1 Kod dla VB.NET

By to wszystko ze sobą zgrać do zdarzenia Click przycisku umieszczonego na Form1 należy dodać następujący kod:

private void cmdMonitor_Click(object sender, System.EventArgs e)
{
     if(Directory.Exists(txtDir.Text))
     {
          fswMonitoring.Path = txtDir.Text;
          fswMonitoring.IncludeSubdirectories = true;
          fswMonitoring.EnableRaisingEvents = true;
          fswMonitoring.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName;
          fswMonitoring.Filter = "*.*";
          fswMonitoring.Renamed += new RenamedEventHandler(OnFileRenamed);
     }
     else
     {
          MessageBox.Show("Directory does not exist. Please type a nie path", "Directory error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }                                             
}

Kod 2 Zdarzenie Click przycisku Monitor (kod w C#)

Private Sub cmdMonitor_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdMonitor.Click
     If Directory.Exists(txtDir.Text) Then
     fswMonitoring.Path = txtDir.Text
     fswMonitoring.IncludeSubdirectories = True
     fswMonitoring.EnableRaisingEvents = True
     fswMonitoring.NotifyFilter = (NotifyFilters.FileName Or NotifyFilters.DirectoryName)
     fswMonitoring.Filter = "*.*"
     AddHandler fswMonitoring.Renamed, AddressOf OnFileRenamed
     Else
     MessageBox.Show("Directory does not exist. Please type a nie path", "Directory error", MessageBoxButtons.OK, MessageBoxIcon.Error)
     End If
End Sub

Kod 2 Zdarzenie Click przycisku Monitor (kod w VB.NET)

Klasa FileSystemWatcher może monitorować pliki lokalnie jak i zdalne oraz na dyskach sieciowych na dowolnym systemie klasy NT (w tym Windows XP). Ze względów oczywistych monitorowanie plików na nośnikach trwałych jak CD-ROM czy DVD-ROM nie ma sensu, gdyż nie zachodzą na nich zmiany. Tabela 2 zawiera atrybuty, które można ustawić w klasie FileSystemWatcher.

W przykładzie, który został stworzony w tym artykule, pod zdarzeniem Click przycisku zostaje ustawiona (podana przez użytkownika w polu TextBox) ścieżka Path, która może, ale nie musi być poprawną ścieżką do katalogu. W tym celu następuje sprawdzenie czy dana ścieżka istnieje w systemie (Direktory.Exists), jeżeli tak następuje ustawienie kolejnych atrybutów. Ze względu na pokazanie możliwości klasy FileSystemWatcher, atrybut IncludeSubdirectories został ustawiony na True, by pokazać, iż można monitorować także podkatalogi i pliki w nich zawarte niż tylko podany katalog. Kolejnym ustawionym atrybutem jest EnabledRaisingEvents (ustawiony na True), który mówi komponentowi, FileSystemWatcher, aby wywoływał zdarzenia mu przypisane za każdym razem, gdy zostanie zmieniony monitorowany plik lub katalog. Za każdym razem, gdy FileSystemWatcher wykryje zajście zmiany w obserwowanej strukturze plików, wywoła odpowiednie zdarzenie, jeżeli wartość EnabledRaisingEvents jest ustawiona na True.

 

Atrybut

Opis

EnabledRaisingEvents

Flaga określająca czy kontrolka FileSystemWatcher jest aktywna (True) lub nieaktywna (False).

Filter

Atrybut określający maskę monitorowanych plików. Standardowo maska ustawiona jest na wszystkie pliki (*.*)

IncludeSubdirectories

Flaga określająca czy kontrolka FileSystemWatcher ma monitorować (True) podkatalogi, czy nie (False).

SynchronizinObject

Atrybut synchronizuje monitorowane zdarzenia do danego obiektu na np.: formularzu (np.: zdarzenie Changed będzie dopiero wywoływane jak zostanie kliknięty przycisk Check).

NotifyFilter

Flaga określająca, jakie zdarzenia mają być monitorowane. Można monitorować następujące zdarzenia:

  • FileName

  • DirectoryName

  • Attribute

  • Size

  • LastWrite

  • LastAccess

  • CreationTime

  • Security

Path

Określa ścieżkę na dysku twardym, jaka ma być monitorowana.

Tabela 2 Atrybuty komponentu FileSystemWatcher

Atrybut NotifyFilter umożliwia określenie typów zdarzeń, które mają być monitorowane przez FileSystemWatcher. W kodzie do artykuły monitorowane są jedynie zdarzenia odpowiedzialne za zmianę nazwy pliku lub katalogu. Typy zdarzeń można łączyć ze sobą za pomocą operacji boolowskiej lub (Or czy | w zależności od języka), by móc określić, które zdarzenia mają być monitorowane i kiedy. Tabela 3 pokazuje wszystkie możliwe typy zdarzeń, które mogą być monitorowane. Na końcu zostaje ustawiony atrybut Filter wartością „*.*”, która korzysta z znaków wieloznacznych (ang. wildcard), co w tym przypadku oznacza „wszystkie pliki z dowolnym rozszerzeniem”. Równie dobrze, można tutaj podać wartość „*.DOC” oznaczającą wszystkie pliki o rozszerzeniu DOC czy „CodeGuru.*” oznaczające „wszystkie pliki o nazwie CodeGuru z dowolnym rozszerzeniem”.

 

Typ zdarzenia

Opis

Attributes

Wywołuje zdarzenie, kiedy atrybut pliku zostanie zmieniony.

CreationTime

Wywołuje zdarzenie, kiedy plik lub katalog zostanie utworzony.

DirectoryName

Wywołuje zdarzenie, kiedy zostanie zmieniona nazwa katalogu.

FileName

Wywołuje zdarzenie, kiedy zostanie zmieniona nazwa pliku.

LastAccess

Wywołuje zdarzenie, kiedy zostanie zmieniona data ostatniego otwarcia pliku lub katalogu.

LastWrite

Wywołuje zdarzenie, kiedy zostanie zmieniona data ostatniego zapisania pliku lub zapisania do katalogu.

Security

Wywołuje zdarzenie, kiedy zostaną zmienione prawda dostępu do pliku lub katalogu.

Size

Wywołuje zdarzenie, kiedy rozmiar pliku lub katalogu ulegnie zmianie.

Tabela 3 Zdarzenia, które mogą być monitorowane

Po ustawieniu wszystkich atrybutów FileSystemWatcher, zostanie dodany kod mówiący aplikacji, co ma zrobić, gdy zajdzie dane zdarzenie (jak ma je obsłużyć, co ma je obsłużyć, jaka funkcja, metoda). W tym celu zostaje umieszczona linijka:

fswMonitoring.Renamed += new RenamedEventHandler(OnFileRenamed);

Kod 3 Event handler C#

AddHandler fswMonitoring.Renamed, AddressOf OnFileRenamed

Kod 3 Event handler VB.NET

Za każdym razem, gdy ma zostać obsłużone dane zdarzenie w komponencie FileSystemWatcher, należy dodać odpowiedni kod, który obsłuży je w aplikacji. Najlepszym przykładem jest aplikacja utworzona w ramach artykułu. Wywołuje ona MessageBox za każdym razem, gdy nastąpi zmiana nazwy pliku i/lub katalogu, który jest monitorowany. W tym celu został dodany event handler wywołujący procedurę OnFileRenamed. Przy dodawaniu event handlerów do danych zdarzeń należy w parametrze przekazać nazwę procedury, która ma obsłużyć, zainstaniałe zdarzenie.

private static void OnFileRenamed(object source, RenamedEventArgs e)
{
     MessageBox.Show("A " + e.OldName + " was renamed to " + e.Name, "OnFileRenamed", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Kod 4 Kod procedury OnFileRenamed (Kod w C#)

Private Shared Sub OnFileRenamed(ByVal source As Object, ByVal e As RenamedEventArgs)
     MessageBox.Show("A " & e.OldName & " was renamed to " & e.Name, "OnFileRenamed", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub

Kod 4 Kod procedury OnFileRenamed (Kod w VB.NET)

Podsumowanie

FileSystemWatcher jest prostym w obsłudze komponentem umożliwiającym śledzenie działań wykonywanych na poszczególnych plikach i katalogach w podanej ścieżce. Może on okazać się bardzo przydatny przy pomniejszych projektach, gdzie SourceControl nie jest wymagany, jednak wiedza o przeprowadzonych zmianach czasami może być przydatna. Może też znaleźć zapotrzebowanie w aplikacjach, które monitorują jakiś katalog, by jak tylko wpadnie do niego plik, pobrać go i przetworzyć informacje w nim zawarte – takim przykładem może być chociażby, SMS, który pewne ustawienia zasysa z jednego katalogu. Wystarczy tam wgrać plik, a zaraz po tym plik jest przez SMS przetwarzany.

Warto także zapoznać się z usługami (Services), gdyż w połączeniu z FileSystemWatcher, mogą one być bardzo przydatne, przykładem takim jest usługa monitorująca pliki w danej ścieżce. Dzięki wykorzystaniu własności usług, użytkownik nawet nie musi wiedzieć o tym, iż jest ona włączona, co jest dodatkowym plusem.

Informacja o załączonym kodzie

Do artykułu został załączony kod w C# i w VB.NET, który oprogramowuje resztę dostępnych zdarzeń w klasie FileSystemWatcher. Warto się jest mu przejrzeć, zawsze można kod przekopiować do swoich projektów zamiast pisać go na nowo.

Kod dodatkowych zdarzeń

// Dodanie event handlerow do cmdMonitor_Click
fswMonitoring.Created += new FileSystemEventHandler(OnFileCreated);
fswMonitoring.Changed += new FileSystemEventHandler(OnFileChanged);
fswMonitoring.Deleted += new FileSystemEventHandler(OnFileDeleted);
//...
private static void OnFileCreated(object source, FileSystemEventArgs e)
{
     MessageBox.Show("A " + e.Name + " was created", "OnFileCreated", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private static void OnFileChanged(object source, FileSystemEventArgs e)
{               
     MessageBox.Show("Change detected on file in " + e.FullPath , "OnFileChanged", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private static void OnFileDeleted(object source, FileSystemEventArgs e)
{
     MessageBox.Show("A " + e.Name + " was deleted", "OnFileDeleted", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Kod 5 Pozostałe zdarzenia (Kod w C#)

´ Dodanie event handlerow do cmdMonitor_Click
AddHandler fswMonitoring.Created, AddressOf OnFileCreated
AddHandler fswMonitoring.Changed, AddressOf OnFileChanged
AddHandler fswMonitoring.Deleted, AddressOf OnFileDeleted
´...
Private Shared Sub OnFileCreated(ByVal source As Object, ByVal e As FileSystemEventArgs)
     MessageBox.Show("A " & e.Name & " was created", "OnFileCreated", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Shared Sub OnFileChanged(ByVal source As Object, ByVal e As FileSystemEventArgs)
     MessageBox.Show("Change detected on file in " & e.FullPath, "OnFileChanged", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Shared Sub OnFileDeleted(ByVal source As Object, ByVal e As FileSystemEventArgs)
     MessageBox.Show("A " & e.Name & " was deleted", "OnFileDeleted", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub

Kod 5 Pozostałe zdarzenia (Kod w VB.NET)

Załączniki:


Podobne artykuły

Komentarze 6 Masz uwagi do tej strony? Napisz

User 79341 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Pierwszy artykul na ten temat jest znaacznie lepszy. Tutaj tylko szybki przeglad ogolnikow pokazujacy praktyczne wykorzystanie.
User 79543 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Postawiłbym 1 za przepisologię stosowaną, ale w porównaniu z artykułem poprzednika, ten jest rewelacyjny - nie zawiera rażących błędów merytorycznych, bo o językowych tego powiedzieć się nie da...
testa1435 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Zbyt pobieżne!
uzytkownik usuniety 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
bez sciemy Panowie!!
User 79379 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
nie dość, że już było to jeszcze ta powtórka jest w tragicznym wydaniu
kamis19823788 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Podobało sie: Artykuł napisany przejrzyście, dobrze się czyta,struktura przemyślana. Rzeczywiscie artykuł o FileSystemWatcher juz był(opublikowany 2 dni wcześniej :)) ale co z tego.... jest napisany w inny sposób - obejmuje mniejszy zakres ale za to jest bardziej konkretny Nie podobalo się: Niektóre osoby oceniające artykuł albo go nie czytały albo wystały ocene na zasadzie - 1 bo nie jest z mojej uczelni... to bez sensu, nie po to piszemy te artykuły. Podsumowanie: 5 za artykuł

Dodaj komentarz

avatar

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Autor Jakub Gutkowski
avatar
 

Załóż konto
CodeGuru to miejsce dla każdego programisty. Przez lata portal rozwijany był siłami społeczności i to właśnie społeczność programistów jest tutaj najważniejsza. CG od wielu lat gromadzi wokół siebie coraz większą grupę pasjonatów. Warto być jej częścią!

Dowiedz się więcej o CodeGuru

Geek Club - Windows Phone

 

MetroOne

Idź na górę strony