.NET : 使用ReadDirectoryChangesW监控文件夹的变化

近日在讨论到之前我发布的“文件同步工具”时,有朋友建议用ReadDirectoryChangesW方法去做监控。我个人觉得,如果在C#中做监控的话,首选还是.NET Framework封装好的FileSystemWatcher去做。但我以为,监控也有监控的烦恼,就是说要一直监控。而一旦中途停止监控,又自然会涉及到一个状态保存的问题。

我刚才将该函数看了一下,做了一个范例,如下。如果有兴趣的朋友,可以参考一下

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode,
  IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes,
  IntPtr hTemplateFile);

[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
static extern bool ReadDirectoryChangesW(IntPtr hDirectory, IntPtr lpBuffer, uint nBufferLength,
  bool bWatchSubtree, uint dwNotifyFilter, out uint lpBytesReturned, IntPtr lpOverlapped,
  IntPtr lpCompletionRoutine);

static void Main(string[] args)
{

    const uint FILE_LIST_DIRECTORY = 0x1;
    const uint FILE_SHARE_READ = 0x1;
    const uint FILE_SHARE_WRITE = 0x2;
    const uint FILE_SHARE_DELETE = 0x4;
    const uint OPEN_EXISTING = 3;
    const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
    const uint FILE_NOTIFY_CHANGE_FILE_NAME = 0x1;
    const uint FILE_NOTIFY_CHANGE_DIR_NAME = 0x2;
    const uint FILE_NOTIFY_CHANGE_LAST_WRITE = 0x10;

    const uint BUFSIZE = 2048;
    string myDocs = @"E:/Temp";
    Console.WriteLine("Monitoring name changes in {0} and subdirectories.", myDocs);

    IntPtr hDir = CreateFile(myDocs, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE |
      FILE_SHARE_DELETE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
    if (hDir == IntPtr.Zero)
    {
        Console.WriteLine("CreateFile failed. " + Marshal.GetLastWin32Error());
        return;
    }

    IntPtr pBuf = IntPtr.Zero;
    try
    {
        pBuf = Marshal.AllocHGlobal((int)BUFSIZE);
        uint bytesReturned;
        while (ReadDirectoryChangesW(hDir, pBuf, BUFSIZE, true, FILE_NOTIFY_CHANGE_FILE_NAME |
               FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, out bytesReturned,
               IntPtr.Zero, IntPtr.Zero))
        {
            string[] actions = new string[] { "(unknown action) ", "Added ", "Removed ",
                              "Modified ", "Old name ", "New name " };
            IntPtr pCurrent = pBuf;
            while (pCurrent != IntPtr.Zero)
            {
                // Read file length (in bytes) at offset 8
                int fileLen = Marshal.ReadInt32(pCurrent, 8);
                // Read file name (fileLen/2 characters) from offset 12
                string file = Marshal.PtrToStringUni((IntPtr)(12 + (int)pCurrent), fileLen / 2);
                // Read action at offset 4
                int action = Marshal.ReadInt32(pCurrent, 4);
                if (action < 1 || action >= actions.Length) action = 0;
                Console.WriteLine(actions[action] + file);

                // Read NextEntryOffset at offset 0 and move pointer to next structure if needed
                int inc = Marshal.ReadInt32(pCurrent);
                pCurrent = inc != 0 ? (IntPtr)(inc + (int)pCurrent) : IntPtr.Zero;
            }
        }
        //else
            //Console.WriteLine("ReadDirectoryChangesW failed. " + Marshal.GetLastWin32Error());
    }
    finally
    {
        if (pBuf != IntPtr.Zero) Marshal.FreeHGlobal(pBuf);
        CloseHandle(hDir);
    }

    Console.Read();
}

本文由作者: 陈希章 于 2009/8/9 8:06:22 发布在: 博客园,转载请注明出处
本文是使用 博客同步和管理系统自动于2009/8/9 8:06:29 从 博客园 同步过来的。原文地址: http://www.cnblogs.com/chenxizhang/archive/2009/08/09/1542115.html ,发表于2009/8/9 0:06:00.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值