2011-08-26 35 views
8

Tôi muốn thăm dò ý kiến ​​hệ thống tệp cho bất kỳ tệp hoặc thư mục con nào đã được thay đổi, thêm hoặc xóa. Tất cả các thay đổi sẽ được phát hiện nhanh chóng nhưng không gây áp lực lên máy. Hệ điều hành là Windows> = Vista, phần quan sát là một thư mục cục bộ.Tôi nên thăm dò ý kiến ​​số lượng lớn các tệp để thay đổi như thế nào?

Thông thường, tôi sẽ sử dụng FileSystemWatcher, nhưng điều này dẫn đến các sự cố với các chương trình khác đã cố gắng xem cùng một vị trí (nổi bật, Windows Explorer). Ngoài ra, tôi nghe nói rằng FSW là không thực sự đáng tin cậy ngay cả đối với các thư mục địa phương và với một bộ đệm lớn.

Vấn đề chính tôi có là số lượng tệp và thư mục có thể rất lớn (đoán 7 chữ số). Đơn giản chỉ cần chạy một kiểm tra cho tất cả các tập tin mỗi giây đã ảnh hưởng đáng kể đến máy tính của tôi. Ý tưởng tiếp theo của tôi là kiểm tra các phần khác nhau của toàn bộ cây/giây để giảm tác động tổng thể, và có thể thêm một loại heuristic, như kiểm tra các tập tin được thay đổi thường xuyên trong kế tiếp nhanh hơn.

Tôi tự hỏi nếu có các mẫu cho loại vấn đề này, hoặc nếu có ai có kinh nghiệm với tình huống này.

+0

Tất cả các thư mục con đều nằm trong một thư mục gốc? Bạn đã gặp phải vấn đề gì với windows explorer? Đây là một mẫu để đảm bảo bạn không bỏ lỡ bất kỳ tin nhắn nào. http://stackoverflow.com/questions/4967095/c-predict-file-system-events-on-folder-delete/4968391#4968391 – adrianm

+0

@adrianm: Có, cùng một gốc. --- Explorer đã không cập nhật giao diện của nó khi một thư mục được theo dõi đã được thay đổi, tôi cho rằng vì FSW đã đánh cắp các sự kiện của nó. – mafu

Trả lời

3

Chúng tôi đã triển khai tính năng tương tự, sử dụng C#. FileSystemWatcher không hiệu quả với các cây thư mục lớn.

thay thế của chúng tôi, đã được sử dụng FSNodes, một struct tạo ra bởi chúng tôi, bằng cách sử dụng các cuộc gọi Windows API sau:

[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); 

gì chúng tôi làm là một chế biến tĩnh. Chúng tôi lưu một cây siêu dữ liệu trên đĩa và so sánh cây thư mục được lưu trữ với cây thư mục được tải, tìm kiếm đã sửa đổi (dựa trên dấu thời gian của nó (nhanh hơn) hoặc trên tệp băm). Ngoài ra, chúng tôi có thể quản lý các tệp đã xóa, thêm và di chuyển, thậm chí đã chuyển đổi (cũng dựa trên băm tệp).

Triển khai này được trộn lẫn với một daemon đã thực hiện mỗi POLL_TIME, hợp lệ đối với chúng tôi. Hy vọng nó giúp.

+0

Bạn có thể giải thích một chút về cách bạn đang sử dụng các cuộc gọi API Win32 không? – Cocowalla

+0

'FindFirstFile' tìm kiếm một thư mục cho một tệp hoặc thư mục con với tên khớp với tên cụ thể (hoặc tên từng phần nếu sử dụng ký tự đại diện). 'FindNextFile' tiếp tục tìm kiếm tập tin từ một cuộc gọi trước đó tới hàm' FindFirstFile' hoặc 'FindFirstFileEx'. Đóng một xử lý tìm kiếm tập tin được mở bởi các hàm 'FindFirstFile' (và các hàm khác). Tôi khuyên bạn nên tìm kiếm trên google để thực hiện tốt hơn API. –

0

Đối với môi trường * nix, bạn có thể sử dụng inotify https://github.com/rvoicilas/inotify-tools/wiki/, hoạt động tốt trong nghiên cứu giới hạn của tôi về nó. Có thể có một phiên bản ở đó làm việc với các cửa sổ mà tôi có ít kinh nghiệm với ... nhanh chóng googling dẫn tôi đến một bản sao java được gọi là jnotify http://jnotify.sourceforge.net/ được quảng cáo để làm việc trên các cửa sổ vì vậy nó có thể là giá trị cố gắng.

1

Dự đoán tốt nhất của tôi là sử dụng tạp chí USN nếu đó là máy cục bộ, bạn có quyền quản trị và phân vùng là NTFS. Tạp chí USN cực kỳ nhanh chóng và đáng tin cậy. Đó là phần đầu dài và liên kết này giải thích mọi thứ: http://www.microsoft.com/msj/0999/journal/journal.aspx

Các vấn đề liên quan