web-dev-qa-db-fra.com

Comment puis-je lire un fichier texte sans le verrouiller?

J'ai un service Windows écrit son journal dans un fichier texte dans un format simple.

Maintenant, je vais créer une petite application pour lire le journal du service et afficher à la fois le journal existant et celui ajouté en tant que vue en direct.

Le problème est que le service verrouille le fichier texte pour l'ajout de nouvelles lignes et que l'application de visualisation verrouille le fichier en lecture.

Le code de service:

void WriteInLog(string logFilePath, data)
{
    File.AppendAllText(logFilePath, 
                       string.Format("{0} : {1}\r\n", DateTime.Now, data));
}

Le code du spectateur:

int index = 0;
private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                using (StreamReader sr = new StreamReader(logFilePath))
                {
                    while (sr.Peek() >= 0)  // reading the old data
                    {
                        AddLineToGrid(sr.ReadLine());
                        index++;
                    }
                    sr.Close();
                }

                timer1.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


private void timer1_Tick(object sender, EventArgs e)
        {
            using (StreamReader sr = new StreamReader(logFilePath))
            {
                // skipping the old data, it has read in the Form1_Load event handler
                for (int i = 0; i < index ; i++) 
                    sr.ReadLine();

                while (sr.Peek() >= 0) // reading the live data if exists
                {
                    string str = sr.ReadLine();
                    if (str != null)
                    {
                        AddLineToGrid(str);
                        index++;
                    }
                }
                sr.Close();
            }
        }

Y at-il un problème dans mon code en lecture et écriture?

Comment résoudre le problème?

83
Homam

Vous devez vous assurer que le service et le lecteur ouvrent le fichier journal de manière non exclusive. Essaye ça:

Pour le service, utilisez une instance FileStream créée comme suit:

var outStream = new FileStream(logfileName, FileMode.Open, 
                               FileAccess.Write, FileShare.ReadWrite);

Pour le lecteur, utilisez la même chose mais changez l’accès au fichier:

var inStream = new FileStream(logfileName, FileMode.Open, 
                              FileAccess.Read, FileShare.ReadWrite);

Bonne chance!

105
Manfred

Explicite configurer le mode de partage lors de la lecture du fichier texte.

using (FileStream fs = new FileStream(logFilePath, 
                                      FileMode.Open, 
                                      FileAccess.Read,    
                                      FileShare.ReadWrite))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        while (sr.Peek() >= 0) // reading the old data
        {
           AddLineToGrid(sr.ReadLine());
           index++;
        }
    }
}
27
heads5150
new StreamReader(File.Open(logFilePath, 
                           FileMode.Open, 
                           FileAccess.Read, 
                           FileShare.ReadWrite))

-> cela ne verrouille pas le fichier.

11
nothrow

Le problème est que lorsque vous écrivez dans le journal, vous verrouillez exclusivement le fichier afin que votre StreamReader ne soit pas autorisé à l'ouvrir du tout.

Vous devez essayer d'ouvrir le fichier en mode en lecture seule.

using (FileStream fs = new FileStream("myLogFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        while (!fs.EndOfStream)
        {
            string line = fs.ReadLine();
            // Your code here
        }
    }
}
7
James

Je me rappelle avoir fait la même chose il y a quelques années. Après quelques requêtes sur Google, j'ai trouvé ceci:

    FileStream fs = new FileStream(@”c:\test.txt”, 
                                   FileMode.Open, 
                                   FileAccess.Read,        
                                   FileShare.ReadWrite);

c'est-à-dire utiliser l'attribut FileShare.ReadWrite sur FileStream ().

(trouvé sur blog de Balaji Ramesh )

5
dotmartin

Avez-vous essayé de copier le fichier, puis de le lire?

Il suffit de mettre à jour la copie chaque fois que de gros changements sont apportés.

1
Tom Gullen