【问题标题】:Exclusive access to text file, to read and overwrite it独占访问文本文件,读取和覆盖它
【发布时间】:2011-04-28 06:38:30
【问题描述】:

我想打开一个文本文件,不允许任何其他进程写入。我知道我可以使用以下 FileStream 做到这一点:

Dim fs As New FileStream(_FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)

一旦我有这样的访问权限,我需要读取所有行(我将使用 StreamReader(fs)),然后我需要写入文件(我将使用 StreamWriter(fs))。

这里的问题是,当我使用文件流而不是文件路径作为参数时,StreamWriter 不允许我将附加模式设置为 false(这样我就可以覆盖文件中的所有文本)。因此,使用 StreamWriter 编写的所有文本都附加到我不想要的文本上。如果我使用带有文件路径的 StreamWriter(这将使我将 append 设置为 false)作为参数而不是文件流,它将因为 FileStream FileShare 而被锁定。我怎样才能仍然拥有读取和写入文件的独占访问权限,但仍然能够覆盖现有文本(附加模式为 false)?

【问题讨论】:

    标签: vb.net file-io filestream streamreader streamwriter


    【解决方案1】:

    这并非不可能,您实际上不需要使用 Apppend = true 初始化的 StreamWriter。您需要做的就是使用 FileStream.Seek() 来确保“文件指针”位于文件末尾。此示例 C# 代码运行良好:

    using (var fs = new FileStream(@"c:\temp\test.txt", FileMode.Open,
            FileAccess.ReadWrite, FileShare.Read)) {
        var sr = new StreamReader(fs);   // NOTE: not using using
        string txt = sr.ReadToEnd();
        fs.Seek(0, SeekOrigin.End);      // Be sure
        var sw = new StreamWriter(fs);
        sw.WriteLine("appended");
        sw.Flush();
    }
    

    请注意此代码中相当多的不适。我将从您的首选值 FileShare.Read 开始。这意味着您将在修改文件时让另一个进程读取该文件。这个过程很有可能会在没有通知的情况下对这个文件中显示的字节感到有点困惑。 FileShare.None 可以很好地工作,确保您的代码永远不会导致任何类型的事故。强烈推荐。

    下一个标志是 // 注意不要使用 using。这很重要,因为 StreamReader 将对您传递的流承担“责任”。如果您在 .NET 代码中执行标准的正确操作,则该类将在 Using 语句结束其范围时关闭流。这不是您想要的,您想保留文件以便写入。

    Seek() 调用执行 StreamWriter 构造函数的 Append 参数所做的事情,确保您附加到文件而不是从头开始随机覆盖文件的某些部分。由于您要追加,因此确保文件中的旧数据被截断没有问题。

    Flush 调用是这里的臭味。您必须调用它来强制写入器刷新其输出缓冲区。如果你不这样做,你写的内容的随机位将从文件中丢失。这通常不是问题,因为您会调用 Close() 或使用 Using 语句来确保编写器已关闭。不是在这种情况下,FileStream 正在发号施令,它会在此处正确关闭文件,但它不知道另一个作家赶上了潮流并想要写入。

    这可行,但它打破了相当多的教条。更典型的模式是 open-read + read + close,open-createnew + write + close。并处理 open-createnew 可能因另一个进程抓取文件而失败的可能性。多任务操作系统的危害,随时准备应对。

    【讨论】:

    • 对不起,我可能不够清楚,我实际上需要它是 append = false,所以我只用我需要的行覆盖整个文件。
    • fs.Seek() 到文件开头并调用 fs.SetLength(0) 截断文件。
    猜你喜欢
    • 2014-02-17
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2021-12-07
    • 2021-01-16
    相关资源
    最近更新 更多