2009-03-26 10 views
15

Je veux ouvrir un fichier pour lecture en mode exclusif, et si le fichier est déjà ouvert par un processus/thread else, je veux recevoir une exception. J'ai essayé le code suivant, mais ne fonctionne pas, même si j'ai ouvert le fichier foo.txt, je peux toujours atteindre l'instruction Console.WriteLine. Des idées?ouvrir le fichier en mode exclusif en C#

static void Main(string[] args) 
{ 
    using (Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open, 
    FileAccess.Read, FileShare.None)) 
    { 
     Console.WriteLine ("I am here"); 
    } 

    return; 
} 
+0

"même si j'ai ouvert le fichier foo.txt" -> comment l'avez-vous ouvert? –

+0

Oui, Mehrdad. Je l'ai ouvert, puis exécuté mon programme, je pouvais toujours lire l'instruction Console.WriteLine. Des idées? – George2

+0

Avec un bloc-notes? Bloc-notes ne verrouille pas le fichier lors de l'exécution. Il lit le fichier en mémoire et le rouvre pour l'écrire lorsque vous enregistrez. –

Répondre

1

Je suggère d'utiliser le membre FileAccess.ReadWrite car certains fichiers peuvent déjà être ouverts, mais vous permettent Read l'accès au dossier. Cependant, je suppose que dans des conditions non-exceptionnelles, tous les fichiers ouverts pour l'accès Read/Write ne permettraient pas votre code à Write au fichier. Bien sûr (comme Mehrdad l'a déjà expliqué), si vous utilisez un éditeur tel que le Bloc-notes pour ouvrir le fichier en tant que test, vous ne pourrez pas en restreindre l'accès car le Bloc-notes ne le verrouille pas du tout.

+0

Merci Cerebrus, vous avez raison et j'utilise le bloc-notes pour l'ouvrir et exécuter mon programme pour tester. Des idées pour vérifier si un fichier est ouvert ou non (par exemple, je veux que mon code puisse vérifier si le bloc-notes l'a ouvert)? – George2

+0

Non, je ne pense pas qu'il y ait ... sauf en attrapant l'exception IOException dans le code qui essaie de lire ensuite le fichier. – Cerebrus

+0

Ma situation est, un thread est la sérialisation (en utilisant la sérialisation XML) dans le fichier, un autre thread de lecture est lu à partir de ce fichier. Je ne veux pas que le thread du lecteur fonctionne sur ce fichier alors que la sérialisation XML est en cours, des idées? – George2

16

Ce que vous faites est la bonne chose. Probablement vous ne faites que le tester incorrectement. Vous devez l'ouvrir avec un programme qui verrouille le fichier lorsqu'il est ouvert. Bloc-notes ne ferait pas. Vous pouvez exécuter votre application deux fois pour voir:

static void Main(string[] args) 
{ 
    // Make sure test.txt exists before running. Run this app twice to see. 
    File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None); 
    Console.ReadKey(); 
} 
+0

Merci Mehrdad, de toute façon de vérifier si un fichier est déjà ouvert par un autre thread/processus? – George2

+0

Je ne pense pas qu'il existe un moyen de savoir si un processus a ouvert un fichier et travaille dessus. Techniquement, le fichier n'est plus ouvert après que le bloc-notes l'ait chargé en mémoire. Je pense que c'est la bonne façon de le faire comme le bloc-notes ou d'autres programmes ne peuvent pas l'ouvrir à nouveau (lire ou enregistrer) ce qui est bien, je pense. –

+0

Merci Mehrdad, j'ai testé vous avez raison. ma situation est, un thread est sérialisation (en utilisant la sérialisation XML) dans le fichier, un autre thread de lecture est lu à partir de ce fichier. Je ne veux pas que le thread du lecteur fonctionne sur ce fichier alors que la sérialisation XML est en cours, des idées? – George2

2

FileShare.None ne fonctionnera que si un autre processus a également ouvert le fichier sans le laisser à partager pour les lectures.

Des programmes tels que le Bloc-notes et Visual Studio ne verrouillent pas les fichiers texte.

+0

Merci Jakob, de toute façon de vérifier si un fichier est déjà ouvert par un autre thread/processus? – George2

+0

Salut Jakob, ma situation est, un thread est sérialisation (en utilisant la sérialisation XML) dans le fichier, un autre thread de lecture est lu à partir de ce fichier. Je ne veux pas que le thread du lecteur fonctionne sur ce fichier alors que la sérialisation XML est en cours, des idées? – George2

+0

Comment procédez-vous à la sérialisation? Lors de la sérialisation, vous devez ouvrir le fichier exclusivement (c'est-à-dire FileAccess.Write et FileShare.None). –

3

Ce que vous avez fait est correct.

Si vous avez besoin quels sont tous les fichiers déjà ouverts, alors il y a une façon de voir par NtQuerySystemInformation

Vous pouvez obtenir une idée de http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx

qui obtient tous les fichiers ouverts dans un répertoire .. qui peut être étendue à un seul fichier si ouvert ou non ...

+0

Merci lakshmanaraj, ma situation est, un thread est la sérialisation (en utilisant la sérialisation XML) dans le fichier, un autre thread de lecture est lu à partir de ce fichier. Je ne veux pas que le thread du lecteur fonctionne sur ce fichier alors que la sérialisation XML est en cours, des idées? – George2

+0

Vous pouvez verrouiller le fichier ou effectuer un mutex en définissant un sémaphore sur – lakshmanaraj

+0

Le nom du fichier est arbitraire, il est donc difficile de le verrouiller. Plus de détails, je copie des fichiers arbitraires de la machine distante à la machine locale en utilisant le thread écrivain, et un thread lecteur va scanner le dossier et lire les informations pour les nouveaux fichiers à venir – George2

2

test en écrivant un programme en mode console simple qui ouvre le fichier et attend ensuite:

static void Main(string args[]) 
{ 
    using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None)) 
    { 
     Console.Write("File is open. Press Enter when done."); 
     Console.ReadLine(); 
    } 
} 

Exécutez ce programme à partir de la ligne de commande (ou d'une autre instance de Visual Studio), puis exécutez votre programme. De cette façon, vous pouvez jouer avec différentes valeurs pour FileMode et FileShare pour vous assurer que votre programme réagit correctement dans tous les cas.

Et, non, vous n'avez pas besoin de vérifier si le fichier est ouvert en premier. Votre code devrait lancer une exception si le fichier est déjà ouvert. Donc tout ce que vous avez à faire est de gérer cette exception.

+0

Salut Jim, ma situation est, un thread copie le fichier (en utilisant la méthode File.Move), et un autre thread est lu à partir du fichier. Je ne veux pas que le thread du lecteur lise une partie du fichier pendant que la copie est en cours (c'est pourquoi je veux avoir un mode ouvert exclusif), mon code posté permet-il de résoudre ce problème? – George2

+0

Oui, votre code résout ce problème. Il n'ouvrira pas le fichier si File.Move est en cours de copie. –

+0

Jim, comment savoir si un programme (!) L'ouvre? Soit le bloc-notes ou autre chose. Ou comment savoir si c'est copié en ce moment? –

Questions connexes