views:

135

answers:

1

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);
}
+3  A: 

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.

md5sum
I thought the idea was to keep the filestream open in the service, so I didn't have to continue to reopen it.
codewright
Will you provide the code you are using to access the stream from your other application.
AndHeCodedIt
Done, for both the service and the reader application.
md5sum
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
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.
md5sum
I posted the file opening code up in the original post now, and it still fails.
codewright
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...
md5sum
You're last suggestion of setting FileShare.ReadWrite for the reader application worked perfectly.
codewright
Excellent, glad I could help... sorry it took so long to get it all lined out. :D
md5sum