Can I prevent a StreamReader from locking a text file whilst it is in use?

G-. picture G-. · Oct 22, 2009 · Viewed 20.9k times · Source

The StreamReader locks a text file whilst it is reading it.
Can I force the StreamReader to work in a "read-only" or "non locking" mode?

My workaround would be to copy the file to a temp location and read it from there but I would prefer to use the StreamReader directly if possible. Any alternative suggetions?

Background:
I've written a small app to get some stats out of a log file. This file is constantly being updating (several times a second) by an outside program lets call AAXXYY.

Reviewing the output suggests that my app may be locking the file and preventing AAXXYY from writing.

This is what I'm doing

    private void btnGetStats_Click(object sender, EventArgs e)
    {
        int countStarts = 0;
        int countEnds = 0;

        IList<string> sessions = new List<string>();

        using(StreamReader stRead = new StreamReader(openFileDialog1.FileName,Encoding.Unicode))
        {
            while(!stRead.EndOfStream)
            {
                string line = stRead.ReadLine();
                if(line.Contains("Session start"))
                {
                    countStarts++;
                    sessions.Add(line.Substring(line.IndexOf("["), line.LastIndexOf("]") - line.IndexOf("[")));
                }
                if (line.Contains("Session end"))
                {
                    countEnds++;
                    sessions.Remove(line.Substring(line.IndexOf("["), line.LastIndexOf("]") - line.IndexOf("[")));
                }
            }
        }

        txtStarts.Text = countStarts.ToString();
        txtEnds.Text = countEnds.ToString();
        txtDifference.Text = (countStarts - countEnds).ToString();

        listBox1.DataSource = sessions;
    }

Answer

Jb Evain picture Jb Evain · Oct 22, 2009

You can pass a FileStream to the StreamReader, and create the FileStream with the proper FileShare value. For instance:

using (var file = new FileStream (openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var reader = new StreamReader (file, Encoding.Unicode)) {
}