2

I have a windows service that writes out log file entries to an XML log file. I maintain a handle to the log file while the service is operational, and close, flush and dispose of it when the service is stopped. The file write operations are by the service only, and I have the filestream open in FileAccess.ReadWrite while sharing is set to FileShare.Read. I would like to be able to open and view this file with an XmlRead() call by another application, but I get an error stating the file is being used by another process. I had read another post on this and was under the impression this was possible: Other Thread.

The writer in use is flushed, closed, and disposed of, and each write the filestream is flushed. Is this just not possible in .Net, or have I perhaps done something wrong? A cutdown version of the code follows:

if (_logFS == null)
        _logFS = new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);

if (!initFile)
{
    _logFS.Seek(-13, SeekOrigin.End);
}

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
using (XmlWriter writer = XmlWriter.Create(_logFS, settings))
{
    if (initFile)
    {
        writer.WriteRaw("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n");
        writer.WriteStartElement("Entries", "http://www.abcdefg.com);
    }

    writer.WriteStartElement("Exception");
    // write out some stuff here.
    writer.WriteEndElement();


    writer.Flush();
    writer.Close();
}

_logFS.Flush();

The file opening code is now as follows:

_LogDS = new XmlLogFile();
using (FileStream logFS = new FileStream(_fileName, FileMode.Open, FileAccess.Read)
{
    _LogDS.ReadXml(logFS);
}
Community
  • 1
  • 1
codewright
  • 197
  • 3
  • 10
  • I have also noticed that while the service is running, that I can open and view the file in Notepad++. Is it possible when I try to load the file via DataSet.XmlRead() that it is trying to get an exclusive lock in my other code? – codewright Sep 15 '10 at 19:44
  • Typo'ed my last comment, I meant DataSet.ReadXml(). – codewright Sep 15 '10 at 19:58

1 Answers1

3

You also need to close the FileStream. At a minimum, you need to close it when your service exits, or when the FileStream would go out of the application's scope.

You should be able to open it as ReadOnly from another application either way, but you have to specify that, it's not a default.

In your service you need to enable the file sharing:

FileStream fs = new FileStream("path", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);

And in your reader application:

FileStream fs = new FileStream("path", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

Without the FileShare.Read, all requests to open the file for reading fail. Any other application requesting to open the file for writing will still fail, for write-enabled sharing you'd use FileShare.ReadWrite. The default option for FileShare is None.

Nathan Wheeler
  • 5,896
  • 2
  • 29
  • 48
  • I thought the idea was to keep the filestream open in the service, so I didn't have to continue to reopen it. – codewright Sep 15 '10 at 19:30
  • Will you provide the code you are using to access the stream from your other application. – TheDevOpsGuru Sep 15 '10 at 19:42
  • The FileShare.Read option has been set from the beginning, which has made me even more curious of the issue. The code to open this file is simply: _LogDS.ReadXml(_fileName); – codewright Sep 15 '10 at 21:32
  • 2
    Make sure you're opening it for read only from your viewer application then. If that's not it, then please post the code you're using to open the file in your viewer, especially if other applications (Notepad++) can open the file. – Nathan Wheeler Sep 15 '10 at 21:34
  • I posted the file opening code up in the original post now, and it still fails. – codewright Sep 15 '10 at 21:39
  • 1
    Try adding a `FileShare.ReadWrite` to your viewer application as I've indicated in my post. I can't recall ever having to do that before, but it's been a while... – Nathan Wheeler Sep 15 '10 at 22:00
  • You're last suggestion of setting FileShare.ReadWrite for the reader application worked perfectly. – codewright Sep 16 '10 at 19:43
  • Excellent, glad I could help... sorry it took so long to get it all lined out. :D – Nathan Wheeler Sep 17 '10 at 13:21