FileSystemWatcher ve Dosya Değişikliklerini İzlemek İçin Yoklama


152

Hem yerel olarak hem de ağ sürücüsünde bir dizinde oluşturulan dosyaları izleyen bir uygulama kurmam gerekiyor.

Misiniz FileSystemWatcheruyandırmasına veya yoklama iyi seçenek olacaktır. Geçmişte her iki yöntemi de kullandım, ama çok fazla kullanmadım.

Her iki yöntemde de hangi sorunlar (performans, güvenilirlik vb.) Var?


3
FileSystemWatcher sızdıran bir soyutlamadır ve en temel durumlardan başka hiçbir şeye güvenilemez. Buraya bakın: stackoverflow.com/a/22768610/129130
Stein Åsmul

1
FileSystemWatcher'ın güvenilirliği konusunda Raymond Chen (Microsoft uzmanı) tarafından verilen bu cevaba referans vermek için bir bağlantı eklemek istersiniz . Ve blogu: Eski Yeni Şey (örneğin FileSystemWatcher'ı arayın).
Stein Åsmul

Yanıtlar:


105

Dosya sistemi izleyicisinin üretim ve test ortamlarında başarısız olduğunu gördüm. Şimdi bunu kolaylık olarak görüyorum, ancak güvenilir olduğunu düşünmüyorum. Desenim, dosya sistemi izleyicisi ile değişiklikleri izlemek, ancak bazen eksik dosya değişikliklerini yakalamak için yoklamak oldu.

Düzenleme: Bir kullanıcı arayüzünüz varsa, kullanıcılarınıza yoklama yerine değişiklikler için "yenileme" olanağı da verebilirsiniz. Bunu bir dosya sistemi izleyicisi ile birleştiririm.


11
Düştüğümü de gördüm. Kullandığımız çözüm, kendi sınıfımızı sarmaktır, burada ALSO sarıcı sınıfı, izleyicinin hala gittiği vesilesiyle kontrol etmek için bir zamanlayıcı kullanır.
Joel Coehoorn

Benzer bir şey yapıyoruz - FileCreated olayına geçirilen dosyayı işledikten sonra, geri dönmeden önce diğer yeni dosyalar için manuel kontrol yapıyoruz. Bu, aynı anda gelen birçok dosyada ortaya çıkan sorunları hafifletiyor gibi görünüyor.
John Sibly

4
Yerel bir dizinde ve bir dosya paylaşımında XP ve Server 2003'te test ettiğimizi ve sahada XP makineleri olduğunu düşünüyorum. Hem yerel dizin hem de dosya paylaşımı ile ilgili sorunlar yaşadık. Karşılaştığımız olası nedenlerden biri, dizinde kısa sürede çok sayıda dosyanın kopyalanması / oluşturulmasıydı.
Jason Jackson

5
Çok yapıcı ne de sadece "bir gün bir hayalet gördüm" devlet için profesyonel değil. Görünüşe göre, iş parçacığının aşağısında, sayfa dışlanabilir arabellek taşmaları hakkında msdn belgesinden bahsederek sorunlarınızı açıklayabilir. Brent'in yaklaşımını kullanmayı denediniz mi?
v.oddou

4
Amazon'da bir gaz sensörü satın aldım ve kaç kişinin işe yaramadığını söylediği, beni doğru şekilde kalibre etmedikleri veya kalibrasyon hakkında bile bilmedikleri zaman şaşırttı ... FileSystemWatcher, yüksek trafikle ilgili sınırlamaları biliyor arabellek boyutu. Neredeyse garantili "başarısız" nedeni. Bu, dokümantasyonda kolayca açıklanmıştır ve çok güvenilir bir çalışma sağlayan (aşağıda belirtildiği gibi) geçici çözümler vardır. Bu sadece "errr, bir şey o zaman işe yaramadı, neden ... kimse buna güvenmemeli" demek için iyi bir cevap değil.
u8it

60

Arabellek dolduğunda sahip olduğum en büyük sorun dosyaları eksik. Düzeltmek için pasta olarak kolay - sadece tamponu artırın. Dosya adlarını ve olaylarını içerdiğini unutmayın, bu yüzden dosyayı beklenen miktarda artırın (deneme yanılma). Sayfalandırılamayan belleği kullanır, bu nedenle bellek azalırsa diğer işlemleri sayfaya zorlayabilir.

Buffer'daki MSDN makalesi: FileSystemWatcher .. ::. InternalBufferSize Özelliği

MSDN başına:

Disk boyutuna değiştirilemeyen disk belleği olmayan bellekten geldiğinden, arabellek boyutunu artırmak pahalıdır, bu nedenle arabelleği olabildiğince küçük tutun. Arabellek taşmasını önlemek için, istenmeyen değişiklik bildirimlerini filtrelemek üzere NotifyFilter ve IncludeSubdirectories özelliklerini kullanın.

Bir seferde beklenen büyük bir parti nedeniyle 16MB kullanıyoruz. İyi çalışıyor ve hiçbir dosyayı kaçırmıyor.

Ayrıca, bir dosyayı işlemeye başlamadan önce tüm dosyaları okuyoruz ... dosya adlarını güvenli bir şekilde önbelleğe alın (bizim durumumuzda, bir veritabanı tablosuna) ve sonra bunları işleyin.

Dosya kilitleme sorunları için, dosyanın kilidinin bir saniye, sonra iki, sonra dört, vb. Biz asla yoklar. Bu yaklaşık iki yıldır hatasız olarak üretilmektedir.


12
Arabellek taşması? Ah, yığın taşması demek istiyorsun.
TheFlash

1
.NET 3.5'ten itibaren: "Arabelleği 4 KB veya daha büyük bir değere ayarlayabilirsiniz, ancak 64 KB'yi geçmemelidir"
brad

9
FileSystemWatcher için maksimum dahili arabellek 64KB ise 16MB'yi nasıl kullanıyorsunuz?
BK

1
@ Jarvis, bir tampon, işleninceye kadar iletildiği gibi bilgi tutmak için yapılandırılmış bir mizaç depolama alanıdır, bu genellikle istekleri geldikleri sırayla dağıtmak istediğiniz gibi bir FIFO veya Kuyruk anlamına gelir, ancak programlarda özyineleme gibi bazı işlemlerde bir FILO veya Yığın yapısı ne kullanılır, Bu durumda kesinlikle programların yığın arabelleğini çağırmak yerine olay kuyruğu tamponuna atıfta bulunuyoruz
MikeT

1
petermeinl.wordpress.com/2015/05/18/tamed-filesystemwatcher Bu yazı, gerçek dünya uygulamalarında dosya sistemini izlemek için yaygın olarak karşılaşılan standart FileSystemWatcher (FSW) sabitleme sorunlarının etrafındaki sağlam paketleyicileri paylaşır.
Kiquenet

35

FileSystemWatcherSıraya değişikliklerin sayısı sağlanan tampon taşması durumunda da, yoğun zamanlarda değişiklik eksik. Bu, .NET sınıfının kendi başına bir kısıtlaması değil, temeldeki Win32 altyapısının bir sınırlamasıdır. Deneyimlerimize göre, bu sorunu en aza indirmenin en iyi yolu bildirimleri olabildiğince çabuk aldatmak ve onlarla başka bir iş parçacığında ilgilenmektir.

Yukarıda @ChillTemp tarafından belirtildiği gibi, izleyici Windows dışındaki paylaşımlarda çalışmayabilir. Örneğin, takılı Novell sürücülerinde çalışmaz.

İyi bir uzlaşmanın, kaçırılan değişiklikleri almak için ara sıra bir anket yapmak olduğuna katılıyorum.


4
Dosya sistemi izleyicisi hızlı bir şekilde art arda birçok olayı gündeme getirmeye başlayabilir. Olay işleyicinizi en az tetiklendikleri kadar hızlı bir şekilde yürütemezseniz, sonunda işleyici olayları yere bırakmaya başlar ve bir şeyleri kaçırırsınız.
Brent Rockwood

17

Ayrıca dosya sistemi izleyicisinin dosya paylaşımlarında güvenilir olmadığını unutmayın. Özellikle dosya paylaşımı Windows olmayan bir sunucuda barındırılıyorsa. FSW, kritik bir şey için kullanılmamalıdır. Veya hiçbir şeyi kaçırmadığını doğrulamak için ara sıra bir anketle kullanılmalıdır.


3
Microsoft, Windows dışındaki dosya paylaşımlarında güvenilir olmadığını kabul etti mi? Windows paylaşımından Linux tabanlı SMB paylaşımına geçiş yaptığımızdan beri bu ilk eli kesinlikle yaşıyoruz.
Sean

1
Farkında olduğumdan değil. Ve eminim bu sadece farklı satıcılar arasında bir suçlama oyunu olacak.
chilltemp

1
Eşlenen sürücülerdeki dosya sistemi izleyicisiyle ilgili sorunlar yaşadık. Harita bağlantısı kesilip yeniden bağlanırsa, dosya izleyici artık değişiklik yapmaz. Kolayca çözüldü ancak dosya sistemi izleyicisi IMHO'ya karşı hala grev.
Richard Dorman

11

Şahsen, FileSystemWatcherbir üretim sistemini kullandım ve iyi çalıştı. Son 6 aydır, 7 gün 24 saat çalışan tek bir hıçkırık yoktu. Tek bir yerel klasörü izliyor (paylaşılan). İşlemesi gereken nispeten az sayıda dosya işlemimiz var (günde 10 olay başlatıldı). Endişelenmem gereken bir şey değil. Kararı yeniden yapmak zorunda kalsaydım tekrar kullanırdım.


7

Şu anda FileSystemWatcherortalama 100 milisaniyede bir güncellenen bir XML dosyasını kullanıyorum .

Ben FileSystemWatcherdüzgün yapılandırıldığı sürece yerel ile asla sorun olmamalıdır bulduk dosyaları .

Uzaktan dosya izleme ve Windows dışı paylaşımlar hakkında deneyimim yok.

Ben doğal olarak güvensiz FileSystemWatcherveya doğrudan burada herkes listelenen kısıtlamaları (Windows olmayan paylaşımlar ve uzaktan dosya izleme) yaşadıysanız , dosya gereksiz ve ek yükü değer yoksaymayı düşünün .


5

Yoklama ile giderdim.

Ağ sorunları FileSystemWatchergüvenilmez olmasına neden olur (hata olayını aşırı yüklerken bile).


5

FileSystemWatcherAğ paylaşımlarında kullanmakta zorlandım . Saf bir Windows ortamındaysanız, bu bir sorun olmayabilir, ancak bir NFS paylaşımını izliyordum ve NFS vatansız olduğundan, izlediğim dosya değiştiğinde hiçbir zaman bir bildirim olmadı.


Aynı sorunu vurdum, ancak FileSystemWatcher NFS kullanarak klasörü paylaşan aynı windows sunucusunda olduğu için beklenmedik oldu. NFS ile bir klasör paylaşma olgusu, dosya sistemi izleyicisinin paylaşımı kullanarak oluşturulan dosyaları uzaktan görmemesine neden olur (yani paylaşımı eşleyen bir Linux'tan). NFS sunucusu dosyaları daha düşük bir katman ve dosya sistemi izleyicisinin devreye girmediğini tetikleyen api katmanını kullanarak yazar, daha fazla bilgi var mı?
Mosè Bottacini

3

Ağ sürücülerinde FSW ile ilgili bazı büyük sorunlar yaşadım: Bir dosyayı silmek her zaman hata olayını, asla silinmiş olayı attı. Bir çözüm bulamadım, şimdi FSW'den kaçıyorum ve yoklama kullanıyorum.

Öte yandan oluşturma olayları iyi çalıştı, bu yüzden sadece dosya oluşturmayı izlemeniz gerekiyorsa, FSW'ye gidebilirsiniz.

Ayrıca, paylaşılmış olsun ya da olmasın, yerel klasörlerde hiç sorun yaşamadım.


3

Olay yönteminden olabildiğince çabuk dönerek, başka bir iş parçacığı kullanarak sorunu benim için çözdü:

private void Watcher_Created(object sender, FileSystemEventArgs e)
{
    Task.Run(() => MySubmit(e.FullPath));
}

2

Her iki FSW kullanma ve yoklama bence zaman ve kaynak israfıdır, ve deneyimli geliştiriciler bunu düşündürmektedir ben şaşırdım. Herhangi bir "FSW özledim" durumunu kontrol etmek için yoklama kullanmanız gerekiyorsa, doğal olarak, FSW'yi tamamen atabilir ve yalnızca yoklama kullanabilirsiniz.

Şu anda, geliştirdiğim bir proje için FSW mi yoksa yoklama mı kullanacağım konusunda karar vermeye çalışıyorum . Cevapları okurken, FSW'nin ihtiyaçları mükemmel bir şekilde karşıladığı durumlar olduğu açıkken, diğer zamanlarda oylamaya ihtiyacınız var . Ne yazık ki, hiçbir cevap aslında vurmuştur performans sadece "güvenilirlik" konularla, (Varsa) farkı. Sorunun bu kısmına cevap verebilecek biri var mı?

Düzenleme: nmclean bir FSW ve yoklama ikisini de kullanarak bu durumlar olabilir neden FSW ve yoklama ikisini de kullanarak geçerliliği için 'nin nokta çok mantıklı bir açıklama olarak görünüyor (Eğer ilgileniyorsanız eğer, yorum tartışmayı okuyabilir) olduğu verimli. Benim için (ve aynı görüşe sahip olan herkes) ışık tuttuğunuz için teşekkür ederiz, nmclean .


1
Dosya değişikliklerine olabildiğince çabuk yanıt vermek isterseniz ne olur? Örneğin dakikada bir anket yaparsanız, bir dosya değişikliği ile uygulamanızın değişikliği alması arasında 1 dakika kadar gecikme olabilir. FSW olayı muhtemelen bundan önce tetiklenecektir. Yani her ikisini de kullanarak olayları olabildiğince az gecikmeyle ele alırsınız, ancak varsa kaçırılan olayları da alırsınız.
rom99

@ rom99 Kesinlikle benim fikrim. Eğer FSW hızlı tepki gerektiren olgularda güvenilmez, hiçbir hızlı yanıt böylece başvurunuz güvenilmez olacak olacak durumlarda olacağından, bunu kullanarak hiçbir nokta yoktur. Daha kısa aralıklarla, bir iş parçacığında yoklama yapmanız gereken şeydir. Her ikisini de yaparak , yoklama sürelerinin yanıtlama sürelerine toleransınız olduğu anlamına gelir, öyleyse neden yalnızca yoklamayı kullanmıyorsunuz?
ThunderGr

5
@ThunderGr "böylece başvurunuz güvenilir olmayacak." - Çoğu durumda, hız güvenilirlik için bir ön koşul değildir. İşin yapılması gerekiyor , ancak bir süre bekleyebilir. Yavaş, güvenilir yoklamayı hızlı, güvenilir olmayan FSW ile birleştirirsek , her zaman güvenilir ve bazen hızlı olan, güvenilir ve asla hızlı olmayan bir uygulama elde ederiz . Sürekli yoklama yaparak FSW'yi kaldırabilir ve aynı maksimum yanıt süresini elde edebiliriz, ancak bu, uygulamanın geri kalanının yanıt verme pahasınadır, bu nedenle yalnızca anında yanıt kesinlikle gerekliyse yapılmalıdır.
nmclean

2
Şimdi yukarıdakiler neden kötü bir argüman? Çünkü hala disk erişimine ihtiyacımız olsa da daha azına ihtiyacımız var . Benzer şekilde, daha az anket yapabilirsiniz. Tüm dosyaları hala kontrol etmemiz, iş yükünün aynı olduğu anlamına gelmez. "FSW ile CPU zamanında yoklama pahalı" ifadesi yanlıştır . FSW için "yakınlık" endişe boşaltma, biz yapabilirsiniz değiştirmek herhangi bir zamanda uygulamanın meşguliyet ölçüde azaltılacak şekilde bir hareketsiz, düşük öncelikli görev, hiç yoklama hala ederken aciliyetinin "tedavi" veren. Tek başına oylamayla aynı dengeyi elde edemezsiniz.
nmclean

9
@nmclean Bunu yaptığınız şekilde netleştirmek için zaman ve enerji harcadığınız için teşekkür ederiz. Bu şekilde koyduğunuzda, elbette çok daha mantıklı. Tıpkı bir önbelleğin özel probleminize uygun olmadığı zamanlar olduğu için, FSW (güvenilir olmadığını kanıtladığında) uygun olmayabilir. Başından beri haklısın. Üzgünüm, onu almam çok zaman aldı.
ThunderGr

1

Değişim yerine create olayıyla çalışmak için çalışma çözümü

Kopyalama, kesme, yapıştırma, taşıma için bile.

class Program
{        

        static void Main(string[] args)
        {
            string SourceFolderPath = "D:\\SourcePath";
            string DestinationFolderPath = "D:\\DestinationPath";
            FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
            FileSystemWatcher.Path = SourceFolderPath;
            FileSystemWatcher.IncludeSubdirectories = false;
            FileSystemWatcher.NotifyFilter = NotifyFilters.FileName;   // ON FILE NAME FILTER       
            FileSystemWatcher.Filter = "*.txt";         
             FileSystemWatcher.Created +=FileSystemWatcher_Created; // TRIGGERED ONLY FOR FILE GOT CREATED  BY COPY, CUT PASTE, MOVE  
            FileSystemWatcher.EnableRaisingEvents = true;

            Console.Read();
        }     

        static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
        {           
                string SourceFolderPath = "D:\\SourcePath";
                string DestinationFolderPath = "D:\\DestinationPath";

                try
                {
                    // DO SOMETING LIKE MOVE, COPY, ETC
                    File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
                }
                catch
                {
                }          
        }
}

Statik depolama kullanarak dosya özniteliği değişikliği olayı sırasında bu dosya izleyici için çözüm

class Program
{
    static string IsSameFile = string.Empty;  // USE STATIC FOR TRACKING

    static void Main(string[] args)
    {
         string SourceFolderPath = "D:\\SourcePath";
        string DestinationFolderPath = "D:\\DestinationPath";
        FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
        FileSystemWatcher.Path = SourceFolderPath;
        FileSystemWatcher.IncludeSubdirectories = false;
        FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;          
        FileSystemWatcher.Filter = "*.txt";         
        FileSystemWatcher.Changed += FileSystemWatcher_Changed;
        FileSystemWatcher.EnableRaisingEvents = true;

        Console.Read();
    }     

    static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
    {
        if (e.Name == IsSameFile)  //SKIPS ON MULTIPLE TRIGGERS
        {
            return;
        }
        else
        {
            string SourceFolderPath = "D:\\SourcePath";
            string DestinationFolderPath = "D:\\DestinationPath";

            try
            {
                // DO SOMETING LIKE MOVE, COPY, ETC
                File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
            }
            catch
            {
            }
        }
        IsSameFile = e.Name;
    }
}

Bu, çoklu tetikleme olayının bu sorunu için geçici bir çözümdür.


0

Dosyaların varlığını alay etmek / saplamak veya yoklama olayı tetiklendiğinde daha "kontrolsüz" fsw olayına güvenmekten çok daha kolay olduğu için, özellikle bir TDD senaryosunda yoklamayı kullanın diyebilirim. + fsw hatalarıyla uğraşan bir dizi uygulama üzerinde çalıştı.

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.