【问题标题】:Log File Locking Issue in C#C# 中的日志文件锁定问题
【发布时间】:2010-09-15 19:19:19
【问题描述】:

我有一个将日志文件条目写入 XML 日志文件的 Windows 服务。我在服务运行时维护日志文件的句柄,并在服务停止时关闭、刷新和处置它。文件写入操作仅由服务进行,我在 FileAccess.ReadWrite 中打开文件流,而共享设置为 FileShare.Read。我希望能够通过另一个应用程序的 XmlRead() 调用打开和查看此文件,但我收到一条错误消息,指出该文件正在被另一个进程使用。我读过另一篇关于此的帖子,并认为这是可能的:Other Thread

正在使用的写入器被刷新、关闭和释放,每次写入文件流都会被刷新。这在.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);
}

【问题讨论】:

  • 我还注意到,在服务运行时,我可以在 Notepad++ 中打开和查看文件。当我尝试通过 DataSet.XmlRead() 加载文件时,它是否可能试图在我的其他代码中获得排他锁?
  • 我的最后一条评论打错了,我的意思是 DataSet.ReadXml()。

标签: c# logging file-io file-locking


【解决方案1】:

您还需要关闭 FileStream。至少,您需要在服务退出或 FileStream 超出应用程序范围时关闭它。

无论哪种方式,您都应该能够从另一个应用程序以只读方式打开它,但您必须指定它,这不是默认设置。

在您的服务中,您需要启用文件共享:

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.ReadWriteFileShare 的默认选项是 None

【讨论】:

  • 我认为这个想法是在服务中保持文件流打开,所以我不必继续重新打开它。
  • 您能否提供用于从其他应用程序访问流的代码。
  • FileShare.Read 选项从一开始就设置好了,这让我对这个问题更加好奇了。打开这个文件的代码很简单:_LogDS.ReadXml(_fileName);
  • 请确保您在查看器应用程序中以只读方式打开它。如果不是这样,请发布您用于在查看器中打开文件的代码,特别是如果其他应用程序 (Notepad++) 可以打开该文件。
  • 尝试将FileShare.ReadWrite 添加到您的查看器应用程序中,正如我在帖子中所指出的那样。我不记得以前必须这样做,但已经有一段时间了......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 2021-06-30
  • 1970-01-01
相关资源
最近更新 更多