2010-10-20 7 views
0

Je voudrais ouvrir un fichier texte et ne pas autoriser d'autres processus à y écrire. Je comprends que je peux le faire avec la FileStream suivante:Accès exclusif au fichier texte, pour le lire et l'écraser

Dim fs As New FileStream(_FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read) 

Une fois que j'ai accès comme cela, je dois lire toutes les lignes (je vais utiliser un StreamReader (fs)), puis je vais devoir écrire le fichier (je vais utiliser un StreamWriter (fs)). Le problème ici est que le StreamWriter ne me permettra pas de mettre le mode d'ajout à faux (donc je peux écraser tout le texte dans le fichier) quand j'utilise le flux de fichiers comme paramètre au lieu du chemin du fichier. Donc tout le texte écrit avec StreamWriter est ajouté sur le texte que je ne veux pas. Si j'utilise un StreamWriter avec le chemin du fichier (ce qui me permettra d'ajouter append à false) en tant que paramètre au lieu du flux de fichiers, il sera verrouillé à cause de FileStream FileShare. Comment puis-je encore avoir un accès exclusif à lire et écrire dans le fichier, mais toujours en mesure d'écraser le texte existant (ajouter le mode faux)?

Répondre

1

Ce n'est pas impossible, vous n'avez pas besoin d'un StreamWriter initialisé avec Apppend = true. Tout ce que vous devez faire est d'utiliser FileStream.Seek() pour vous assurer que le 'pointeur de fichier' est positionné à la fin du fichier. Cet exemple de code C# a bien fonctionné:

using (var fs = new FileStream(@"c:\temp\test.txt", FileMode.Open, 
     FileAccess.ReadWrite, FileShare.Read)) { 
    var sr = new StreamReader(fs); // NOTE: not using using 
    string txt = sr.ReadToEnd(); 
    fs.Seek(0, SeekOrigin.End);  // Be sure 
    var sw = new StreamWriter(fs); 
    sw.WriteLine("appended"); 
    sw.Flush(); 
} 

Notez la quantité d'inconfort dans ce code. Je voudrais commencer avec FileShare.Read, votre valeur préférée. Cela implique que vous laisserez un autre processus lire le fichier pendant que vous le bricolez. Il y a de bonnes chances que ce processus devienne un peu confus au sujet des octets apparaissant dans ce fichier sans préavis. Pourrait bien fonctionner, FileShare.None garantit que votre code peut jamais causer une sorte de malchance. Fortement recommandé.

Le drapeau suivant est // Note n'utilisant pas. C'est important car StreamReader prendra la "responsabilité" du flux que vous lui transmettez. Si vous effectuez le code standard .NET correct, la classe va fermer le flux lorsque l'instruction Using termine sa portée. Ce n'est pas ce que vous voulez, vous voulez garder le fichier afin de pouvoir y écrire. L'appel Seek() fait ce que fait l'argument Append du constructeur StreamWriter, assurez-vous que vous ajoutez au fichier au lieu d'écraser aléatoirement des parties du fichier depuis le début. Puisque vous voulez ajouter, aucun problème à propos de s'assurer que les anciennes données dans le fichier sont tronquées.

L'appel Flush est le bit malodorant ici. Vous avez pour l'appeler pour forcer l'écrivain pour vider son tampon de sortie. Si vous ne le faites pas, des morceaux aléatoires de ce que vous écrivez seront manquants dans le fichier. Ce n'est normalement pas un problème car vous appelez Close() ou utilisez l'instruction Using pour vous assurer que l'éditeur est fermé. Pas dans ce cas, le FileStream appelle les clichés, il fermera correctement le fichier ici mais il ne sait pas qu'un autre écrivain a sauté sur le train en marche et veut écrire.

Cela fonctionnera mais il casse un bon nombre de dogmes. Le modèle le plus typique est open-read + read + close, open-createnew + write + close. Et traitant de la possibilité que l'open-createnew pourrait échouer parce qu'un autre processus a saisi le fichier. Les dangers d'un système d'exploitation multi-tâches, toujours être prêt à faire face à cela.

+0

Désolé je ne dois pas avoir été assez clair, j'ai en fait besoin d'être append = false, donc je écraser le fichier entier avec seulement les lignes dont j'ai besoin. – Matt

+0

fs.Seek() au début du fichier et appelez fs.SetLength (0) pour tronquer le fichier. –

Questions connexes