2011-08-26 29 views
8

Dosya sistemini değiştirilmiş, eklenmiş veya kaldırılmış dosyalar veya alt dizinler için yoklamak istiyorum. Tüm değişiklikler hızlı bir şekilde tespit edilmeli, ancak makineye basınç uygulanmadan. İşletim Sistemi Windows> = Vista, gözlenen kısım yerel bir dizindir.Değişiklikler için çok sayıda dosyayı nasıl seçmeliyim?

Tipik olarak, bir FileSystemWatcher'a başvururdum, ancak bu, aynı noktayı (belirgin olarak Windows Gezgini) izlemeyi deneyen diğer programlarla ilgili sorunlara yol açtı. Ayrıca, FSW'nin yerel klasörler ve büyük bir arabellek için bile güvenilir olmadığını duydum.

Sahip olduğum ana sorun, dosya ve dizin sayısının çok büyük olabileceği (7 basamaklı tahmin). Her saniyede bir dosya için bir kontrol yapmak, makinemi etkileyebilir.

Bir sonraki düşüncem, genel etkiyi azaltmak için saniyedeki tüm ağacın farklı bölümlerini kontrol etmekti ve muhtemelen daha sık aralıklarla sık sık değiştirilen dosyaları incelemek gibi bir tür heuristik ekleyecekti.

Bu tür sorunların kalıpları olup olmadığını veya bu durumla ilgili deneyimleri olup olmadığını merak ediyorum.

+0

Tüm alt klasörler tek bir kök altında mı? Windows gezgini ile ne tür problemler yaptın? İşte herhangi bir mesajı kaçırmamak için bir desen. http://stackoverflow.com/questions/4967095/c-predict-file-system-events-on-folder-delete/4968391#4968391 – adrianm

+0

@adrianm: Evet, aynı kök. - Explorer, izlenen bir klasör değiştiğinde görüntüsünü güncellemedi, sanırım FSW olaylarını çaldı. – mafu

cevap

3

C# kullanarak benzer bir özellik uyguladık. FileSystemWatcher, büyük dizin ağaçlarıyla etkisizdi.

Bizim alternatif, aşağıdaki Windows API çağrılarını kullanarak, FSNodes, bizim tarafımızdan oluşturulan bir yapı kullanıyordu:

[StructLayout(LayoutKind.Sequential)] 
     private struct FILETIME 
    { 
     public uint dwLowDateTime; 
     public uint dwHighDateTime; 
    }; 

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 
     private struct WIN32_FIND_DATA 
    { 
     public FileAttributes dwFileAttributes; 
     public FILETIME ftCreationTime; 
     public FILETIME ftLastAccessTime; 
     public FILETIME ftLastWriteTime; 
     public uint nFileSizeHigh; 
     public uint nFileSizeLow; 
     public int dwReserved0; 
     public int dwReserved1; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)] 
     public string cFileName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)] 
     public string cAlternate; 
    } 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool FindClose(IntPtr hFindFile); 

    [DllImport("kernel32", CharSet=CharSet.Unicode)] 
    private static extern IntPtr FindFirstFile(
     string lpFileName, out WIN32_FIND_DATA lpFindFileData); 

    [DllImport("kernel32", CharSet=CharSet.Unicode)] 
    private static extern bool FindNextFile(
     IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); 

Yapmamız statik işlenmesidir. Bir metadata ağacını diske kaydeder ve saklanan dizin ağacını karşıdan yüklenenle karşılaştırırız, değiştirilmiş arama (zaman damgasına göre (daha hızlı) veya dosya karması üzerinde). Ayrıca, silinmiş, eklenmiş ve taşınmış, hatta taşınan değiştirilmiş dosyaları da yönetebiliriz (ayrıca dosya karmasına dayanarak).

Bu uygulama, her POLL_TIME için yürütülen bir arka plan ile karıştırıldı, bizim için geçerliydi. Umarım yardımcı olur.

+0

Win32 API çağrılarını nasıl kullandığınızı biraz açıklayabilir misiniz? – Cocowalla

+0

'FindFirstFile', belirli bir ada sahip bir ada sahip bir dosya veya alt dizin için bir dizin arar (veya joker karakterler kullanılıyorsa kısmi ad). 'FindNextFile', önceki bir çağrıdan' FindFirstFile' veya 'FindFirstFileEx' işlevine yapılan bir dosya aramasına devam eder. FindFirstFile (ve diğer) işlevleri tarafından açılan bir dosya arama tutamacını kapatır. API'yi daha iyi anlamak için bir google araması öneririm. –

0

* nix ortamları için, üzerinde yaptığım sınırlı araştırmayla harika çalışan https://github.com/rvoicilas/inotify-tools/wiki/ numaralı telefonu kullanabilirsiniz. Orada daha az deneyime sahip pencereler ile çalışan orada bir sürümü olabilir ... hızlı googling beni denemeye değer olabilir böylece windows üzerinde çalışmak için ilan edilen jnotify http://jnotify.sourceforge.net/ adında bir java klon yol açtı.

1

En iyi tahminim, yerel bir makineyse USN günlüğünü kullanmak, yönetici ayrıcalıklarına sahip olmak ve bölümleri NTFS'dir. USN dergi son derece hızlı ve güvenilirdir. Bu uzun bir topis ve bu bağlantı her şeyi açıklar: http://www.microsoft.com/msj/0999/journal/journal.aspx

İlgili konular