【问题标题】:C# read locked fileC#读取锁定文件
【发布时间】:2018-04-19 02:59:19
【问题描述】:

到目前为止,我已经尝试了所有方法,但都没有成功。

我想要完成的是,我想打开并锁定一个文件一段时间。 在我打开并锁定文件后,我尝试打开同一个文件只是为了阅读。

string filePath = "test.ini";

// Open and lock the file
FileStream configurationFile = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
configurationFile.Lock(1, configurationFile.Length);

// Open the same file just to read it
using (FileStream bufferStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (StreamReader sr = new StreamReader(bufferStream))
    {
        string line;
        while ((line = sr.ReadLine()) != null)    // <--- Here I get the error
        {
            CustomMessageBox.Show(line);
        }
    }
}

我实际上可以使用 FileStream 和 StreamReader 打开文件,但是当谈到将 StreamReader 与例如 sr.ReadLine() 一起使用时,它会引发异常,即该文件正在被另一个进程使用。

正如这里提到的Reading a file used by another process [duplicate],FileShare 属性应该是 ReadWrite 但这没有帮助。

我也尝试了所有可用的编码,如StreamReader(bufferStream, Encoding.*),但也没有用。

我忽略了一些简单的事情吗?

【问题讨论】:

  • 这是documented in LockFile,托管函数将其包装起来:“如果锁定进程第二次打开文件,它无法通过第二个句柄访问指定区域,直到它解锁该区域。”您也必须使用第一个流进行任何您希望进行的阅读。
  • 我是否理解您想锁定文件以进行写入,同时仍允许读取?如果是这样,这是stackoverflow.com/q/3279071/120955的副本吗?
  • 因为您无论如何都要锁定整个文件 - 您可以使用 FileShare.None 打开它,而不是使用 Lock。
  • 您是否尝试通过使用第一个SafeFileHandle 将第二个流传递给带有FileStream(SafeFileHandle handle, FileAccess access) 签名的构造函数来打开第二个流?我相信通过适当的共享标志,您最终会得到两个绑定到单个文件的托管流。
  • @AlexSeleznyov:绑定到单个文件句柄。这很重要,因为文件指针与该句柄相关联(除其他外)。如果您使用以下技巧,应特别小心:“FileStream 假定它对句柄具有独占控制权。在 FileStream 还持有句柄时读取、写入或查找可能会导致数据损坏。对于数据安全,使用句柄前调用Flush,使用句柄后避免调用Close以外的任何方法。”我会完全避免这样做。

标签: c# filestream streamreader


【解决方案1】:

这是因为根据 Windows,您正在构建文件的新句柄。 当文件被锁定时,它不允许任何其他句柄被其他流获取。你最好像这样修复你的代码:

using (FileStream bufferStream = new FileStream(filePath, FileMode.Open, 
                FileAccess.Read, FileShare.ReadWrite))
{
   bufferStream.Lock(0L, bufferStream.Length);
   using (StreamReader sr = new StreamReader(bufferStream))
   {
       string line;
       while ((line = sr.ReadLine()) != null)    // <--- Here I get the error
       {
         CustomMessageBox.Show(line);
       }
   }

   // dispose lock
   bufferStream.Unlock(0L, bufferStream.Length);
}

【讨论】:

【解决方案2】:

您正在文件流上调用Lock,并传递参数以指示您希望锁定整个文件。根据文档,

锁定文件流的范围使锁定进程的线程可以独占访问该文件流的范围。

如果您不想锁定文件,请不要致电Lock

【讨论】:

  • 我刚刚拍了一张脸,你说得对。在我注释掉锁行之后,它就像一个魅力,谢谢。
猜你喜欢
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多