Jak sprawdzić dużą liczbę plików pod kątem zmian?

Chciałbym sprawdzić system plików pod kątem zmienionych, dodanych lub usuniętych plików lub podkatalogów. Wszystkie zmiany należy wykryć szybko, ale bez nacisku na maszynę. System operacyjny to Windows > = Vista, obserwowana część to katalog lokalny.

Zazwyczaj uciekałem się do FileSystemWatcher, ale to doprowadziło do problemów z innymi programami, które próbowały oglądać to samo miejsce (w szczególności Windows Explorer). Słyszałem też, że FSW nie jest tak naprawdę niezawodny nawet dla lokalnych folderów i z dużym buforem.

Głównym problemem jest to, że liczba plików i katalogów może być bardzo duża (chyba 7-cyfry). Po prostu uruchamianie sprawdzania wszystkich plików co sekundę znacząco wpłynęło na mój komputer.

Moim następnym pomysłem było sprawdzanie różnych części całego drzewa na sekundę, aby zmniejszyć ogólny wpływ i ewentualnie dodać coś w rodzaju heurystyki, jak sprawdzanie plików, które zmieniają się często w szybszym tempie.

Zastanawiam się czy są jakieś wzory do tego rodzaj problemu, lub jeśli ktoś ma doświadczenia z tej sytuacji.

Author: mafu, 2011-08-26

3 answers

Zaimplementowaliśmy podobną funkcję, używając C#. FileSystemWatcher był nieefektywny z dużymi drzewami katalogów.

Naszą alternatywą było użycie FSNodes, struktury stworzonej przez nas, wykorzystującej następujące wywołania Windows API:

    [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);
To, co robimy, to statyczne przetwarzanie. Zapisujemy drzewo metadanych na dysku i porównujemy przechowywane drzewo katalogów z załadowanym, wyszukując zmodyfikowane (na podstawie jego znacznika czasu (szybciej) lub hasha pliku). Ponadto możemy zarządzać usuniętymi, dodawanymi i przenoszonymi, nawet moved-zmodyfikowane pliki (również oparte na hash pliku).

Ta implementacja wymieszana z demonem, który wykonywał ją każdego POLL_TIME, była dla nas ważna. Mam nadzieję, że to pomoże.

 3
Author: Daniel Peñalba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-17 08:33:58

Moim najlepszym pomysłem byłoby użycie dziennika USN, jeśli jest to maszyna lokalna, masz uprawnienia administratora, a partycje są NTFS. USN journal jest niezwykle szybki i niezawodny. Jest to długi topis i ten link wyjaśnia wszystko: http://www.microsoft.com/msj/0999/journal/journal.aspx

 1
Author: pg0xC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-03 19:10:51

Dla środowisk * nix możesz użyć inotify https://github.com/rvoicilas/inotify-tools/wiki / , które świetnie sprawdzały się w moich ograniczonych badaniach nad nim. Może być wersja, która działa z systemem windows, z którym mam mniejsze doświadczenie ... szybkie googlowanie doprowadziło mnie do klonu Javy o nazwie jnotify http://jnotify.sourceforge.net / który jest reklamowany do pracy na windows, więc może warto spróbować.

 0
Author: Baldur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-26 11:47:15