Bir dizini izlemek için FileSystemWatcher'ı kullanma


101

Bir dizini izlemek ve içine bırakılan dosyaları başka bir dizine taşımak için bir Windows Forms Uygulaması kullanıyorum.

Şu anda dosyayı başka bir dizine kopyalayacaktır, ancak başka bir dosya eklendiğinde hata mesajı olmadan bitecektir. Bazen üçüncüyle bitmeden önce iki dosyayı kopyalar.

Bunun nedeni konsol uygulaması yerine Windows Form Uygulaması kullanmam mı? Programın bitmesini durdurmanın ve dizini izlemeye devam etmenin bir yolu var mı?

private void watch()
{
  this.watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += OnChanged;
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

public void Dispose()
{
  // avoiding resource leak
  watcher.Changed -= OnChanged;
  this.watcher.Dispose();
}

Yanıtlar:


144

Sorun, bildirim filtreleriydi. Program, kopyalanmakta olan bir dosyayı açmaya çalışıyordu. LastWrite dışındaki tüm bildirim filtrelerini kaldırdım.

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastWrite;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

6
Merhaba, ben bu yaklaşımı kullanıyordum ama bir dosyayı kopyaladığımda olay iki kez ortaya çıkıyor: dosya boş oluşturulduğunda (kopyalama başlar) ve kopyalama bittiğinde bir kez daha. Bu yinelenen olaydan nasıl kaçınılır, herhangi bir filtre bunu özel bir kontrol olmaksızın işleyebilir mi?
dhalfageme

@dhalfageme Klasörde uygulamam için anlamlı bir şey göründüğünde her iki olayı da kontrol ederim.
Eftekhari

30

Dosya işleme kodunu sağlamadınız, ancak herkesin böyle bir şeyi ilk yazarken yaptığı aynı hatayı yaptığınızı varsayıyorum: dosya oluşturulur oluşturulmaz dosya gözlemcisi olayı ortaya çıkacaktır. Ancak dosyanın bitmesi biraz zaman alacaktır. Örneğin 1 GB dosya boyutunu ele alalım. Dosya başka bir program tarafından oluşturulabilir (Explorer.exe bir yerden kopyalayarak) ancak bu işlemin tamamlanması birkaç dakika sürecektir. Etkinlik, oluşturma sırasında ortaya çıkar ve dosyanın kopyalanmaya hazır olmasını beklemeniz gerekir.

Bu işlevi bir döngü içinde kullanarak bir dosyanın hazır olmasını bekleyebilirsiniz .


25

Bunun nedeni, izleyicinin bir yönteme yerel değişken olarak bildirilmesi ve yöntem bittiğinde çöpün toplanması olabilir. Sınıf üyesi olarak ilan etmelisiniz. Takip etmeyi dene:

FileSystemWatcher watcher;

private void watch()
{
  watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

18
watcherdeğişkeni canlı tutulur (çöp toplanmaz) çünkü Değişen etkinliğe abone olmuştur.
adospace

1
Bunun aslında EnableRaisingEvents olarak ayarlandığına inanıyorum true. Üye olay işleyicilerinin durumunun çöp toplama ile ilgisi olduğunu sanmıyorum. Sanırım EnableRaisingEvents, bu durumda olumlu bir şekilde adlandırabileceğim özel bir davranışa sahip.
Matias Grioni
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.