我能防止StreamReader在使用时锁定文本文件吗?

24

StreamReader在读取文本文件时会锁定文件。
我能否强制StreamReader以“只读”或“非锁定”模式工作?

我的解决方法是将文件复制到临时位置,然后从那里读取,但如果可能的话,我更愿意直接使用StreamReader。 有其他替代建议吗?

背景:
我编写了一个小应用程序,以从日志文件中获取一些统计信息。这个文件正在被外部程序 AAXXYY 不断更新(每秒几次)。

查看输出表明,我的应用程序可能正在锁定该文件并阻止 AAXXYY 的写入。

以下就是我的做法

    private void btnGetStats_Click(object sender, EventArgs e)
    {
        int countStarts = 0;
        int countEnds = 0;

        IList<string> sessions = new List<string>();

        using(StreamReader stRead = new StreamReader(openFileDialog1.FileName,Encoding.Unicode))
        {
            while(!stRead.EndOfStream)
            {
                string line = stRead.ReadLine();
                if(line.Contains("Session start"))
                {
                    countStarts++;
                    sessions.Add(line.Substring(line.IndexOf("["), line.LastIndexOf("]") - line.IndexOf("[")));
                }
                if (line.Contains("Session end"))
                {
                    countEnds++;
                    sessions.Remove(line.Substring(line.IndexOf("["), line.LastIndexOf("]") - line.IndexOf("[")));
                }
            }
        }

        txtStarts.Text = countStarts.ToString();
        txtEnds.Text = countEnds.ToString();
        txtDifference.Text = (countStarts - countEnds).ToString();

        listBox1.DataSource = sessions;
    }
2个回答

52

你可以将FileStream传递给StreamReader,并使用正确的FileShare值创建FileStream。例如:

using (var file = new FileStream (openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var reader = new StreamReader (file, Encoding.Unicode)) {
}

+1 这个很好用。谢谢。虽然我不得不用FileStream和StreamReader替换“var”。var原本是用来做什么的?这是VB吗?我认为这个答案应该被编辑一下,把那些东西改掉,但我没有足够的声望去自己做。 - G-.
8
关于 'var' 关键字,请参见此链接:http://msdn.microsoft.com/en-us/library/bb383973.aspx。该关键字是在 C# 3.0+ 中新增的。 - pyrocumulus
啊哈。谢谢云。我自作自受,因为我在黑暗时代工作。可惜我不能点赞评论 :-) - G-.
哦,我可以给评论点赞。就这样。 - G-.
在这种情况下,您也可以调用dispose方法 - reader.dispose()。 - Brian
1
@Brian,using语句在完成时会自动调用dispose。 - Rufus L

6

我觉得需要提供一些背景信息,StreamReader并不会在读取文件时锁定它,仅在写入时才会锁定。请看下面来自StreamReader类的代码:

 new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.SequentialScan);

请注意MSDN中默认的FileAccess.Read参数(http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx)。
允许打开文件以供读取。如果未指定此标志,任何读取文件的请求(由该进程或另一个进程发出)都将失败,直到关闭文件。但是,即使指定了此标志,仍可能需要其他权限才能访问文件。
为了允许读写,请使用FileAccess.ReadWrite(如Jb Evain所建议)。
允许打开文件以供读取或写入。如果未指定此标志,任何请求打开文件以供读取或写入(由该进程或另一个进程)都将失败,直到关闭文件。但是,即使指定了此标志,仍可能需要其他权限才能访问文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接