.NET : 使用ReadDirectoryChangesW监控文件夹的变化
2009-08-09 08:06
351 查看
近日在讨论到之前我发布的“文件同步工具”时,有朋友建议用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.
[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.
相关文章推荐
- .NET : 使用ReadDirectoryChangesW监控文件夹的变化
- delphi的文件夹监控控件,直接封装成可视化的控件,拖一下即可代码。核心为:ReadDirectoryChangesW
- Windows监控文件变化(ReadDirectoryChangesW)
- ReadDirectoryChangesW 监控文件夹 (一个简单的监控示例程序)(文件被修改了,也可以探测到)
- ReadDirectoryChangesW监控文件夹
- ReadDirectoryChangesW 监控文件夹 (一个简单的监控示例程序)
- 监控目录文件变化的ReadDirectoryChangesW 函数学习总结
- VC++文件监控(一) ReadDirectoryChangesW
- 关于Win32 API 函数 ReadDirectoryChangesW(CDirectoryChangeWatcher by Wes Jones)的使用
- VC++文件监控(一) ReadDirectoryChangesW
- ReadDirectoryChangesW()---同步模式监控目录中的文件
- ReadDirectoryChangesW实现文件监控的封装类
- VC++文件监控 ReadDirectoryChangesW
- VC++文件监控 ReadDirectoryChangesW
- ReadDirectoryChangesW---异步方式(IO完成端口)监控目录中的文件
- ReadDirectoryChangesW 写成的 文件监控类
- CDirectoryChangeWatcher - ReadDirectoryChangesW all wrapped up
- CDirectoryChangeWatcher - ReadDirectoryChangesW all wrapped up
- 理解 ReadDirectoryChangesW
- SetEvent,ResetEvent、ReadDirectoryChangesW、WaitForSingleObject最优博文