Проблема блокировки файла журнала в C # - PullRequest
2 голосов
/ 15 сентября 2010

У меня есть служба 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 Ответ

3 голосов
/ 15 сентября 2010

Вам также необходимо закрыть 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.

...