2010-11-20 4 views
3

J'ai déjà réussi à voir les modifications de fichiers et de dossiers avec FileSystemWatcher.Moniteur de fichiers/dossiers C#

Mon problème est que je ne peux pas faire une différence entre les fichiers et les dossiers. Il est possible qu'un fichier et un dossier aient les mêmes noms de chemin.

Pour l'événement delete je ne peux même pas utiliser un workarround sale avec tester File.Exists (chemin) ou Directory.Exists (chemin) car le fichier/dossier est déjà supprimé lorsque la méthode est appelée.

Peut-être que cet objet a l'info que j'ai besoin, mais je ne l'ai pas trouvé:

FileSystemEventArgs e 

Je veux seulement savoir si l'élément modifié était un fichier ou un dossier.

Répondre

1

que j'ai trouvé une solution qui est propre et fonctionne toujours:

Le paramètre standard d'un observateur est pour les fichiers et les dossiers. Cela n'a aucun sens à mes yeux puisque je ne peux pas savoir quel type l'objet a changé.

Il est possible de créer deux filewatchers. Un pour les fichiers et un pour les dossiers. Ensuite, il vous suffit de modifier les paramètres par défaut comme suit:

// for file 
fileSysWatchFile.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite; 
// for folder 
fileSysWatchDir.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.LastWrite; 
+0

Le seul problème est que FSW utilise ThreadPool, donc si vous utilisez plusieurs observateurs, l'ordre des événements que vous allez traiter peut ne pas refléter réalité. La seule solution que j'ai trouvée jusqu'ici est d'utiliser Change Journals comme mentionné par ho1, ou d'écrire votre propre FileSystemWatcher en utilisant [this] (http://qualapps.blogspot.cz/2010/05/understanding-readdirectorychangesw.html) et [ceci] (http://qualapps.blogspot.cz/2010/05/understanding-readdirectorychangesw_19.html).Juste jeter là-bas pour quiconque qui viendra sur ce fil à l'avenir. – Paya

1

Vous pouvez vérifier si elle a le Répertoireattribute:

var attributes = File.GetAttributes(@"c:\somepath"); 
if ((attributes & FileAttributes.Directory) == FileAttributes.Directory) 
{ 
    // it's a directory 
} 
else 
{ 
    // it's a file 
} 

Bien sûr, si elle a déjà été supprimé cela ne fonctionnera pas et vous ne serez pas en mesure de dire le type.

+0

Etes-vous sûr que cela fonctionnera dans le cas où l'OP met en évidence où le fichier/répertoire est supprimé? –

+0

Non, cela ne fonctionnera pas s'il a déjà été supprimé. –

+0

Cela échoue si le répertoire/fichier a déjà été supprimé. – jason

0

Il n'est pas possible de récupérer le type de l'élément supprimé sauf si vous avez une liste de mappages path-> type avant de pouvoir rechercher le dernier type de l'élément supprimé.

+0

??? ... donc si j'ai un fichier = C: \ nom et un dossier = C: \ nom, je ne peux pas savoir lequel a été changé? – fpdragon

+1

Vous ne pouvez pas avoir un fichier et un répertoire portant le même nom dans le même dossier. – ThiefMaster

+0

de toute façon si elle est déjà supprimée, vous ne pouvez même pas savoir s'il s'agit d'un fichier ou d'un répertoire – fpdragon

2

En supposant que c'est sur un volume NTFS, je pense que vous pourriez faire ce dont vous avez besoin en regardant le Change Journals. Plus précisément, le code de contrôle FSCTL_READ_USN_JOURNAL et en regardant le FileAttributes du USN_RECORD pour voir si c'est un FILE_ATTRIBUTE_DIRECTORY.

Vous trouverez un exemple ici (en C++, mais pourrait éventuellement se traduire par C# ou autrement peut-être juste écrire un petit C++ dll pour appeler à partir de votre application): Walking a Buffer of Change Journal Records