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

2

24

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;
    }
Sohn answered 22/10, 2009 at 10:34 Comment(0)
B
53

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)) {
}
Birkett answered 22/10, 2009 at 10:40 Comment(6)
+1 this works nicely. Thank you. Although I had to replace "var" with FileStream & StreamReader. What was var suppossed to do? Is that VB? I think this answer should be edited to change those but I dont have the rep to do it myselfSohn
About the 'var' keyword, see this link: msdn.microsoft.com/en-us/library/bb383973.aspx. That keyword is new in C# 3.0+.Examination
Aha. Thanks cloud. Serves me right for working in the dark ages. Shame I can't +1 a comment :-)Sohn
Oh, I can +1 a comment. There we goSohn
You can also call the dispose method - reader.dispose() in this instance.Logography
@Logography the using statements call dispose automatically when they completeHaematite
H
6

Thought I'd add some context, StreamReader does not lock a file for reading only for writing whist it is being read. Take a look at the code below from the StreamReader class.

 new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.SequentialScan);

Notice the default FileAccess.Read parameter taken for MSDN http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx

Allows subsequent opening of the file for reading. If this flag is not specified, any request to open the file for reading (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.

Again taken from MSDN to allow reading and writing use FileAccess.ReadWrite instead (as suggested by Jb Evain).

Allows subsequent opening of the file for reading or writing. If this flag is not specified, any request to open the file for reading or writing (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.

Hautrhin answered 17/10, 2012 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.