views:

50

answers:

3

I have a windows services written in C# .NET. The service is running on a internal timer, every time the interval hits, it will go and try to read this log file into a String.

My issue is every time the log file is read, the service seem to lock the log file. The lock on that log file will continue until I stop the windows service. At the same time the service is checking the log file, the same log file needs to be continuously updated by another program. If the file lock is on, the other program could not update the log file.

Here is the code I use to read the text log file.

        private string ReadtextFile(string filename)
    {
        string res = "";
        try
        {
            System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            System.IO.StreamReader sr = new System.IO.StreamReader(fs);

            res = sr.ReadToEnd();

            sr.Close();
            fs.Close();
        }
        catch (System.Exception ex)
        {
            HandleEx(ex);
        }

        return res;
    }

Thank you.

+2  A: 

I would suggest closing the file in a Finally statement to make sure it gets executed

System.IO.FileStream fs = null;
System.IO.StreamReader sr = null;
try{
    fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
    sr = new System.IO.StreamReader(fs);

    res = sr.ReadToEnd();
}
catch (System.Exception ex)
{
    HandleEx(ex);
}
finally
{
   if (sr != null)  sr.Close();
   if (fs != null)  fs.Close();
}

Or try using the using statement:

using (FileStream fileStream = File.Open(filename, FileMode.Open, FileAccess.Read))
{
    ...
}
Glennular
+1 for the `using` tip.
Mike Atlas
A: 

You need to use the four-argument form of FileStream and include the access mask FileShare.Read:

var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);

This way the file is opened in a way that allows for multiple concurrent readers. Additionally, the code that is writing the file also needs to open it with FileShare.Read.

JSBangs
I think you should use FileShare.Write instead of Read (accordind to http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx)
munissor
I have tried the 4 argument form, and even with FileShare.Delete. It still doesn't work. Seems that a service will keep locking the file until service is stopped.
rvpals
@rvpals, did you update both the code that's writing the file and the code that's reading the file?
JSBangs
No, I only write the code that reads the log file. There is a different program that will keep writing to the log file.
rvpals
+1  A: 

Try using:

using (FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
    using(StreamReader sr = new System.IO.StreamReader(fs))
    {
        res = sr.ReadToEnd();
    }
}
marapet
Tried, still doesn't work. Thanks
rvpals
Does the other program release the lock? Do you have an anti-virus on this box? Is it really the service that is locking the file (verify with process explorer)?
marapet
Hi, I use ProcessExplorer to find out that yes, it's my service that is holding to the file.
rvpals