2011-08-26 7 views
8

変更、追加、削除されたファイルやサブディレクトリのファイルシステムをポーリングしたいと思います。すべての変更は迅速に検出されますが、マシンに負担はかかりません。 OSはWindows> = Vista、観測される部分はローカルディレクトリです。変更のために多数のファイルをどのようにポーリングする必要がありますか?

通常、私はFileSystemWatcherに頼っていましたが、これは同じ場所(目立つようにWindowsエクスプローラ)を見ようとした他のプログラムで問題を引き起こしました。また、FSWはローカルフォルダや大きなバッファでも信頼性がないと聞きました。

私の主な問題は、ファイルとディレクトリの数が非常に多い(7桁の推測)ことがあるということです。毎秒すべてのファイルのチェックを実行するだけで、私のマシンに顕著な影響がありました。

私の次のアイデアは、ツリー全体のさまざまな部分をチェックして全体的な影響を減らし、おそらく頻繁に頻繁に変更されるファイルをチェックするようなヒューリスティックを追加することでした。

この種の問題のパターンがあるのか​​、誰かがこのような状況に遭遇したことがあるのでしょうか。

+0

すべてのサブフォルダは1つのルートの下にありますか? Windowsエクスプローラではどのような問題がありましたか?あなたがメッセージを見逃さないようにするためのパターンです。 http://stackoverflow.com/questions/4967095/c-predict-file-system-events-on-folder-delete/4968391#4968391 – adrianm

+0

@adrianm:はい、同じルートです。 ---監視されたフォルダが変更されたとき、エクスプローラはそのビューを更新しませんでした。FSWがそのイベントを盗んだためです。 – mafu

答えて

3

C#を使用して同様の機能を実装しました。 FileSystemWatcherは、大きなディレクトリツリーでは効率的ではありませんでした。

私たちの代わりに、次のWindows API呼び出しを使用して、FSNodes、私たちが作成した構造体を使用していました:

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

は、私たちがやっていることは、静的な処理です。我々は、メタデータツリーをディスクに保存し、格納されたディレクトリツリーとロードされたものとを比較し、変更された(タイムスタンプ(速い)またはファイルハッシュに基づいて)検索する。また、削除されたファイル、追加されたファイル、移動されたファイル、移動されたファイル(ファイルハッシュに基づくファイル)も管理できます。

この実装は、それぞれのPOLL_TIMEを実行するデーモンと組み合わされており、私たちにとっては有効でした。それが役に立てば幸い。

+0

Win32 API呼び出しの使用方法について少し説明できますか? – Cocowalla

+0

'FindFirstFile'は、特定の名前(またはワイルドカードが使用されている場合は部分名)と一致する名前を持つファイルまたはサブディレクトリをディレクトリから検索します。 'FindNextFile'は' FindFirstFile'または 'FindFirstFileEx'関数への前回の呼び出しからのファイル検索を続けます。 'FindFirstFile'(および他の)関数によってオープンされたファイル検索ハンドルを閉じます。 Googleの検索をお勧めします。 –

0

* nix環境では、inotify https://github.com/rvoicilas/inotify-tools/wiki/を使用できますが、これは私の限られた研究ではうまくいきました。そこには私が少ない経験を持っているウィンドウで動作するバージョンがあるかもしれません...クイックグーグルは、jnotify http://jnotify.sourceforge.net/と呼ばれるJavaクローンに私を導いたので、試してみる価値があるかもしれないので、ウィンドウで動作するように広告されます。

1

ローカルマシンで、管理者権限を持ち、パーティションがNTFSの場合は、USNジャーナルを使用することをお勧めします。 USNジャーナルは非常に高速で信頼性があります。これは長いトップスです。このリンクはすべてを説明しています: http://www.microsoft.com/msj/0999/journal/journal.aspx

関連する問題