zoukankan      html  css  js  c++  java
  • Obtaining Directory Change Notifications(微软的例子,使用FindFirstChangeNotification,FindNextChangeNotification,FindCloseChangeNotification API函数)

    An application can monitor the contents of a directory and its subdirectories by using change notifications. Waiting for a change notification is similar to having a read operation pending against a directory and, if necessary, its subdirectories. When something changes within the directory being watched, the read operation is completed. For example, an application can use these functions to update a directory listing whenever a file name within the monitored directory changes.

    An application can specify a set of conditions that trigger a change notification by using the FindFirstChangeNotification function. The conditions include changes to file names, directory names, attributes, file size, time of last write, and security. This function also returns a handle that can be waited on by using the wait functions. If the wait condition is satisfied, FindNextChangeNotification can be used to provide a notification handle to wait on subsequent changes. However, these functions do not indicate the actual change that satisfied the wait condition.

    Use FindCloseChangeNotification to close the notification handle.

    To retrieve information about the specific change as part of the notification, use the ReadDirectoryChangesW function. This function also enables you to provide a completion routine.

    To track changes on a volume, see change journals.

    The following example monitors the directory tree for directory name changes. It also monitors a directory for file name changes. The example uses theFindFirstChangeNotification function to create two notification handles and the WaitForMultipleObjects function to wait on the handles. Whenever a directory is created or deleted in the tree, the example should update the entire directory tree. Whenever a file is created or deleted in the directory, the example should refresh the directory.

    Note  

    This simplistic example uses the ExitProcess function for termination and cleanup, but more complex applications should always use proper resource management such as FindCloseChangeNotification where appropriate.

     
     
    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <tchar.h>
    
    void RefreshDirectory(LPTSTR);
    void RefreshTree(LPTSTR);
    void WatchDirectory(LPTSTR);
    
    void _tmain(int argc, TCHAR *argv[])
    {
        if(argc != 2)
        {
            _tprintf(TEXT("Usage: %s <dir>
    "), argv[0]);
            return;
        }
    
        WatchDirectory(argv[1]);
    }
    
    void WatchDirectory(LPTSTR lpDir)
    {
       DWORD dwWaitStatus; 
       HANDLE dwChangeHandles[2]; 
       TCHAR lpDrive[4];
       TCHAR lpFile[_MAX_FNAME];
       TCHAR lpExt[_MAX_EXT];
    
       _tsplitpath_s(lpDir, lpDrive, 4, NULL, 0, lpFile, _MAX_FNAME, lpExt, _MAX_EXT);
    
       lpDrive[2] = (TCHAR)'\';
       lpDrive[3] = (TCHAR)'';
     
    // Watch the directory for file creation and deletion. 
     
       dwChangeHandles[0] = FindFirstChangeNotification( 
          lpDir,                         // directory to watch 
          FALSE,                         // do not watch subtree 
          FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes 
     
       if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) 
       {
         printf("
     ERROR: FindFirstChangeNotification function failed.
    ");
         ExitProcess(GetLastError()); 
       }
     
    // Watch the subtree for directory creation and deletion. 
     
       dwChangeHandles[1] = FindFirstChangeNotification( 
          lpDrive,                       // directory to watch 
          TRUE,                          // watch the subtree 
          FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir name changes 
     
       if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) 
       {
         printf("
     ERROR: FindFirstChangeNotification function failed.
    ");
         ExitProcess(GetLastError()); 
       }
     
    
    // Make a final validation check on our handles.
    
       if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL))
       {
         printf("
     ERROR: Unexpected NULL from FindFirstChangeNotification.
    ");
         ExitProcess(GetLastError()); 
       }
    
    // Change notification is set. Now wait on both notification 
    // handles and refresh accordingly. 
     
       while (TRUE) 
       { 
       // Wait for notification.
     
          printf("
    Waiting for notification...
    ");
    
          dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 
             FALSE, INFINITE); 
     
          switch (dwWaitStatus) 
          { 
             case WAIT_OBJECT_0: 
     
             // A file was created, renamed, or deleted in the directory.
             // Refresh this directory and restart the notification.
     
                 RefreshDirectory(lpDir); 
                 if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
                 {
                   printf("
     ERROR: FindNextChangeNotification function failed.
    ");
                   ExitProcess(GetLastError()); 
                 }
                 break; 
     
             case WAIT_OBJECT_0 + 1: 
     
             // A directory was created, renamed, or deleted.
             // Refresh the tree and restart the notification.
     
                 RefreshTree(lpDrive); 
                 if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
                 {
                   printf("
     ERROR: FindNextChangeNotification function failed.
    ");
                   ExitProcess(GetLastError()); 
                 }
                 break; 
     
             case WAIT_TIMEOUT:
    
             // A timeout occurred, this would happen if some value other 
             // than INFINITE is used in the Wait call and no changes occur.
             // In a single-threaded environment you might not want an
             // INFINITE wait.
     
                printf("
    No changes in the timeout period.
    ");
                break;
    
             default: 
                printf("
     ERROR: Unhandled dwWaitStatus.
    ");
                ExitProcess(GetLastError());
                break;
          }
       }
    }
    
    void RefreshDirectory(LPTSTR lpDir)
    {
       // This is where you might place code to refresh your
       // directory listing, but not the subtree because it
       // would not be necessary.
    
       _tprintf(TEXT("Directory (%s) changed.
    "), lpDir);
    }
    
    void RefreshTree(LPTSTR lpDrive)
    {
       // This is where you might place code to refresh your
       // directory listing, including the subtree.
    
       _tprintf(TEXT("Directory tree (%s) changed.
    "), lpDrive);
    }
    
    
    

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa365261(v=vs.85).aspx

  • 相关阅读:
    文件操作小练习
    阶段练习1
    copy小练习
    小练习
    str 小列题
    条款50:使用自定义的new以及delete的时机会
    条款49:了解new-handle行为
    简单的说一下:tarits技法就是一种模板元编程,起可以将本来处于运行期的事拉到编译期来做,增加了运行效率。 看以非模板元编程的例子,就是前面的那个例子:
    条款47:请使用traits class表示类型信息
    条款46:需要类型转换的时候请为模板定义非成员函数
  • 原文地址:https://www.cnblogs.com/findumars/p/8082635.html
Copyright © 2011-2022 走看看