Проблема блокировки файла журнала в C#

У меня есть служба Windows, которая записывает записи файла журнала в файл журнала XML. Я поддерживаю дескриптор файла журнала, пока служба работает, и закрываю, сбрасываю и удаляю его, когда служба остановлена. Операции записи файлов выполняются только службой, и у меня есть файловый поток, открытый в FileAccess.ReadWrite, в то время как для общего доступа установлено значение FileShare.Read. Я хотел бы иметь возможность открывать и просматривать этот файл с помощью вызова XmlRead() другого приложения, но я получаю сообщение об ошибке, указывающее, что файл используется другим процессом. Я прочитал еще один пост на эту тему, и у меня сложилось впечатление, что это возможно: Другая тема.

Используемый модуль записи сбрасывается, закрывается и удаляется, и при каждой записи поток файлов сбрасывается. Это просто невозможно в.Net, или я, возможно, сделал что-то не так? Ниже приведена сокращенная версия кода:

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();

Код открытия файла теперь выглядит следующим образом:

_LogDS = new XmlLogFile();
using (FileStream logFS = new FileStream(_fileName, FileMode.Open, FileAccess.Read)
{
    _LogDS.ReadXml(logFS);
}

1 ответ

Решение

Вам также необходимо закрыть FileStream. Как минимум, вам необходимо закрыть его, когда ваша служба завершит работу или когда FileStream выйдет из области приложения.

Вы должны быть в состоянии открыть его как ReadOnly из другого приложения в любом случае, но вы должны указать это, это не по умолчанию.

В вашем сервисе вам необходимо включить общий доступ к файлам:

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

И в вашем приложении для чтения:

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

Без FileShare.Read, все запросы на открытие файла для чтения не выполняются. Любое другое приложение, запрашивающее открытие файла для записи, все равно не будет выполнено, для совместного использования с включенной записью вы будете использовать FileShare.ReadWrite, Опция по умолчанию для FileShare является None,

Другие вопросы по тегам