Pergunta

No Windows, existe uma maneira fácil de saber se uma pasta possui um subarquivo que foi alterado?

Eu verifiquei e a data da última modificação na pasta não é atualizada quando um subarquivo é alterado.

Existe uma entrada de registro que eu possa definir que modificará esse comportamento?

Se for importante, estou usando um volume NTFS.

Em última análise, eu gostaria de ter essa capacidade de um programa C++.

A verificação recursiva de um diretório inteiro não funcionará para mim porque a pasta é muito grande.

Atualizar:Eu realmente preciso de uma maneira de fazer isso sem um processo em execução enquanto a mudança ocorre.Portanto, instalar um observador de sistema de arquivos não é ideal para mim.

Atualização2:O bit de arquivo também não funcionará porque tem o mesmo problema da data da última modificação.O bit de arquivo do arquivo será definido, mas as pastas não.

Foi útil?

Solução

Esse artigo deveria ajudar.Basicamente, você cria um ou mais objetos de notificação, como:

HANDLE dwChangeHandles[2]; 
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("\n ERROR: FindFirstChangeNotification function failed.\n");
     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("\n ERROR: FindFirstChangeNotification function failed.\n");
     ExitProcess(GetLastError()); 
   }

e então você espera por uma notificação:

 while (TRUE) 
   { 
   // Wait for notification. 
      printf("\nWaiting for notification...\n");

      DWORD dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 
         FALSE, INFINITE); 

      switch (dwWaitStatus) 
      { 
         case WAIT_OBJECT_0: 

         // A file was created, renamed, or deleted in the directory.
         // Restart the notification. 
             if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
             {
               printf("\n ERROR: FindNextChangeNotification function failed.\n");
               ExitProcess(GetLastError()); 
             }
             break; 

         case WAIT_OBJECT_0 + 1: 

         // Restart the notification. 
             if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
             {
               printf("\n ERROR: FindNextChangeNotification function failed.\n");
               ExitProcess(GetLastError()); 
             }
             break; 

         case WAIT_TIMEOUT:

         // A time-out 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("\nNo changes in the time-out period.\n");
            break;

         default: 
            printf("\n ERROR: Unhandled dwWaitStatus.\n");
            ExitProcess(GetLastError());
            break;
      }
   }
}

Outras dicas

Isto talvez seja um exagero, mas o Kit IFS do MS ou do FDDK da OSR pode ser uma alternativa.Crie seu próprio driver de filtro de sistema de arquivos com monitoramento simples de todas as alterações no sistema de arquivos.

ReadDirectoryChangesW

Alguns excelentes exemplos de código em este artigo do CodeProject

Se você não puder executar um processo quando a alteração ocorrer, não há muito o que fazer, exceto verificar o sistema de arquivos e verificar a data/hora da modificação.Isso exige que você armazene a última data/hora de cada arquivo e compare.

Você pode acelerar isso usando o bit de arquivo (embora isso possa atrapalhar seu software de backup, proceda com cuidado).

Um bit de arquivo é um atributo de arquivo presente em muitos sistemas de arquivos de computador, principalmente gordos, FAT32 e NTFS.O objetivo de um bit de arquivo é rastrear alterações incrementais nos arquivos para fins de backup, também chamado de arquivamento.

Como o bit de arquivo é um bit binário, ele é 1 ou 0 ou, neste caso, mais frequentemente chamado de conjunto (1) e limpo (0).O sistema operacional define o bit de arquivo sempre que um arquivo for criado, movido, renomeado ou modificado de alguma forma.O bit de arquivo representa, portanto, um dos dois estados:"Alterado" e "não alterado" desde o último backup.

Os bits de arquivo não são afetados por simplesmente ler um arquivo.Quando um arquivo é copiado, o bit de arquivo do arquivo original não é afetado, no entanto, o bit de arquivo da cópia será definido no momento em que a cópia é feita.

Então o processo seria:

  1. Limpe o bit de arquivo em todos os arquivos
  2. Deixe o sistema de arquivos mudar com o tempo
  3. Verifique todos os arquivos - qualquer um com o conjunto de bits de arquivo alterado

Isso eliminará a necessidade de seu programa manter o estado e, como você está apenas examinando as entradas do diretório (onde o bit está armazenado) e elas estão agrupadas, deve ser muito, muito rápido.

Entretanto, se você puder executar um processo durante as alterações, então você vai querer dar uma olhada no FileSystemWatcher aula.Aqui está um exemplo de como você pode usá-lo.

Também existe em .LÍQUIDO (para futuros pesquisadores deste tipo de problema)

Talvez você possa deixar um processo em execução na máquina observando as alterações e criando um arquivo para ler mais tarde.

-Adão

Talvez você possa usar o NTFS 5 Change Journal com DeviceIoControl conforme explicado aqui

Se você não se opõe ao uso do .NET, o FileSystemWatcher class cuidará disso para você com bastante facilidade.

Na postagem dupla, alguém mencionou:Coletor de eventos WMI

Ainda procurando uma resposta melhor.

Nada fácil - se você tiver um aplicativo em execução, poderá usar a API de notificação de alteração de arquivo Win32 (FindFirstChangeNotification), conforme sugerido nas outras respostas.aviso:Por volta de 2000, o antivírus em tempo real Trend Micro agruparia as alterações, tornando necessário o uso de buffers realmente grandes ao solicitar as listas de alterações do sistema de arquivos.

Se você não tiver um aplicativo em execução, poderá ativar o registro em diário NTFS e verificar se há alterações no diário http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx mas isso pode ser mais lento do que verificar todo o diretório quando o número de alterações for maior que o número de arquivos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top