如何在不锁定的情况下读取文本文件?

Hom*_*mam 84 c# file-io

我有一个Windows服务以简单的格式将其日志写入文本文件.

现在,我将创建一个小应用程序来读取服务的日志,并将现有日志和添加的日志显示为实时视图.

问题是服务锁定文本文件以添加新行,同时查看器应用程序锁定文件以供读取.

服务代码:

void WriteInLog(string logFilePath, data)
{
    File.AppendAllText(logFilePath, 
                       string.Format("{0} : {1}\r\n", DateTime.Now, data));
}
Run Code Online (Sandbox Code Playgroud)

观众代码:

int index = 0;
private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                using (StreamReader sr = new StreamReader(logFilePath))
                {
                    while (sr.Peek() >= 0)  // reading the old data
                    {
                        AddLineToGrid(sr.ReadLine());
                        index++;
                    }
                    sr.Close();
                }

                timer1.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


private void timer1_Tick(object sender, EventArgs e)
        {
            using (StreamReader sr = new StreamReader(logFilePath))
            {
                // skipping the old data, it has read in the Form1_Load event handler
                for (int i = 0; i < index ; i++) 
                    sr.ReadLine();

                while (sr.Peek() >= 0) // reading the live data if exists
                {
                    string str = sr.ReadLine();
                    if (str != null)
                    {
                        AddLineToGrid(str);
                        index++;
                    }
                }
                sr.Close();
            }
        }
Run Code Online (Sandbox Code Playgroud)

我的代码在读写方式上有什么问题吗?

如何解决问题?

Man*_*red 109

您需要确保服务和阅读器都非独占地打开日志文件.试试这个:

对于服务,请使用如下创建的FileStream实例:

var outStream = new FileStream(logfileName, FileMode.Open, 
                               FileAccess.Write, FileShare.ReadWrite);
Run Code Online (Sandbox Code Playgroud)

对于读者使用相同但更改文件访问权限:

var inStream = new FileStream(logfileName, FileMode.Open, 
                              FileAccess.Read, FileShare.ReadWrite);
Run Code Online (Sandbox Code Playgroud)

祝好运!

  • 另外,值得注意的是`FileStream`实现了`IDisposable` (2认同)

hea*_*150 27

在读取文本文件时显式设置共享模式.

using (FileStream fs = new FileStream(logFilePath, 
                                      FileMode.Open, 
                                      FileAccess.Read,    
                                      FileShare.ReadWrite))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        while (sr.Peek() >= 0) // reading the old data
        {
           AddLineToGrid(sr.ReadLine());
           index++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 没有必要显式关闭流,因为StreamReader.Dispose自动关闭它. (2认同)
  • 我相信文件共享应该在BOTH读写流上设置,而不仅仅是读取. (2认同)

not*_*row 12

new StreamReader(File.Open(logFilePath, 
                           FileMode.Open, 
                           FileAccess.Read, 
                           FileShare.ReadWrite))
Run Code Online (Sandbox Code Playgroud)

- >这不会锁定文件.


Jam*_*mes 7

问题是当您写入日志时,您将文件专门锁定,因此根本不允许您的StreamReader打开它.

您需要尝试以只读模式打开文件.

using (FileStream fs = new FileStream("myLogFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        while (!fs.EndOfStream)
        {
            string line = fs.ReadLine();
            // Your code here
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


dot*_*tin 5

我记得几年前做过同样的事情.经过一些谷歌查询,我发现了这个:

    FileStream fs = new FileStream(@”c:\test.txt”, 
                                   FileMode.Open, 
                                   FileAccess.Read,        
                                   FileShare.ReadWrite);
Run Code Online (Sandbox Code Playgroud)

即使用FileStream()上的FileShare.ReadWrite属性.

(在Balaji Ramesh的博客上找到)