C++ WinApi: ReadDirectoryChangesW() Ayant Reçu Le Double De Notifications
J'essaie de comprendre ReadDirectoryChangesW
fonction, donc je peux être effectivement informés sur le changement du contenu dans plusieurs répertoires (fichiers écrasés, les fichiers supprimés, renommés, etc..).
Une de mes récentes observations est que pour chaque fichier opération d'écriture, je reçois toujours deux notifications pour seul fichier.
J'ai tracé que très attentivement, et je suis sûr que si je l'écrasement d'un fichier (disons un .fichier txt avec un nouveau contenu essentiellement de gagner quelques lettres de l'intérieur), ReadDirectoryChangesW()
m'avise deux fois par que d'enregistrer le fichier.
C'est une chose sérieuse, comme je m'attends à être averti qu'une seule fois par le changement. Je ne souhaite pas involontairement répéter les opérations qui devrait se produire qu'une seule fois dans ma demande.
Est ce problème connu? Est-il un moyen pour ne recevoir que une notification par un changement, s'il vous plaît? Est-il moyen efficace pour d'éviter les doubles notifications?
J'utilise:
- Le C++
- Visual Studio 2012
- Windows 7 x64
J'ai une utilisation assez basique code pour faire mes tests, mais vous voulez le voir, il est donc ici:
HANDLE hDir = CreateFile(
lpDir,
FILE_LIST_DIRECTORY,
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
int nCounter = 0;
FILE_NOTIFY_INFORMATION strFileNotifyInfo[1024];
DWORD dwBytesReturned = 0;
while(TRUE)
{
if( ReadDirectoryChangesW ( hDir, (LPVOID)&strFileNotifyInfo, sizeof(strFileNotifyInfo), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, &dwBytesReturned, NULL, NULL) == 0)
{
ErrorCheck(_T("Reading Directory Change"));
}
else
{
_tcout << _T("File Modified: ") << strFileNotifyInfo[0].FileName << endl;
_tcout << _T("Loop: ") << nCounter++ << endl;
}
}
double possible de Filesystemwatcher entrées en double
bonjour et merci pour votre idée. Il est en effet très intelligent. J'ai essayé mes tests avec un autre drapeau. Je peux dire, que par exemple, FILE_NOTIFY_CHANGE_ATTRIBUTES renvoie deux notifications. Cela peut être expliqué, que sur l'écrasement des fichiers, plus d'un attribut est normalement changé?
OriginalL'auteur Bunkai.Satori | 2012-12-26
Vous devez vous connecter pour publier un commentaire.
ReadDirectoryChangesW() a une très myope vue du système de fichiers. Il voit chaque changement du système de fichiers et consciencieusement les rapports entre eux. Et oui, il y a souvent plus d'un lorsque vous écrivez dans un fichier. C'est un détail d'implémentation du système de fichiers particulier que vous utilisez, mais toute une commune dans Windows conserve également une entrée de répertoire pour un fichier qui stocke les métadonnées du fichier.
Donc, vous voyez l'écriture pour le fichier de données. Mais vous aussi voir modification de l'entrée de répertoire. En particulier, la taille du fichier, susceptibles de changer lorsque vous écrivez un fichier et ajouter des données au fichier. Et la dernière écriture et de dernier accès à celles enregistrées dans le répertoire d'entrée. L'api est contraire à l'aveugle à la nature du changement, il ne voit que le bas niveau de l'écriture. Il est également complètement inconscients de ce processus particulier a demandé de l'écrire.
C'est quelque chose que vous aurez à traiter avec, il n'y a aucun moyen de distinguer ces écritures. Tout ce que vous savez est "le fichier a été modifié". Comment, pourquoi, par qui et à quelle fréquence est totalement introuvable.
Quelque chose d'autre, vous devrez faire face est que, au moment où la notification est générée, le processus qui écrit le fichier est très probable d'avoir encore un verrou sur le fichier. Qui vous empêche d'en faire quelque chose d'utile avec le fichier vous-même. Comme la lecture du fichier ou de la copie, il est susceptible d'échouer. Vous devez attendre jusqu'à ce que le processus est terminé avec le fichier et a fermé sa poignée pour le fichier. Il n'y a aucun moyen de découverte de cette, autres qu'en essayant d'ouvrir le fichier vous-même et de refuser tout échange. Cela nécessite une minuterie, périodiquement, en essayant d'acquérir un verrou sur le fichier vous-même. Une fois que vous avez que de la plomberie en place, plus d'une notification de changement pour le fichier n'a plus d'importance.
OriginalL'auteur Hans Passant
C'est le résultat de l'opération du code en cours d'exécution simultanément avec la procmon enregistrement après enregistrement du fichier dans le bloc-notes. Il y a deux avertit de ReadDirectoryChangesW() et deux avertit de procmon.
2 IRP_MJ_WRITE 1 bloc-notes (WriteFile) 1 à partir du Gestionnaire de Cache du Système (CcWriteBehind)
FILE_NOTIFY_CHANGE_LAST_WRITE
msdn.microsoft.com/en-us/library/windows/desktop/... les états "Tout changer à la dernière écriture de fichiers dans le regardé répertoire ou sous-arborescence des causes d'une notification de modification de l'opération d'attente pour le retour. Le système d'exploitation détecte un changement à la dernière écriture uniquement lorsque le fichier est écrit sur le disque. Pour les systèmes d'exploitation que l'utilisation extensive de la mise en cache, la détection se produit uniquement lorsque le cache est suffisamment vidé."halo et merci pour votre explication. Votre analyse est excellente et explique parfaitement ce problème. Je suis juste désolé, je n'ai pas été en mesure de trouver la réponse sur mon propre. Il semble, que le Moniteur de Processus de Sysinternals.com est un outil très puissant.
salut Nik, oui, j'ai lu que le paragraphe à partir de la documentation. Il semble que Sergmat a expliqué que, et je vais devoir surveiller toutes les notifications sur la base du temps écoulé, je vais donc éviter les doubles.
Sa supposition peut-être raison mais je ne sais pas qui il l'a expliqué. Le comportement observe-t-il, va à l'encontre de ce que les états de documentation.
Il n'y a rien à expliquer, dans la capture d'écran, tout est visible.C'est le résultat de l'opération du code en cours d'exécution simultanément avec la procmon enregistrement après enregistrement du fichier dans le bloc-notes. Il y a deux avertit de ReadDirectoryChangesW() et deux avertit de procmon.
OriginalL'auteur sergmat