File.Open用于在Windows中执行文件时拒绝读取访问

Veg*_*und 4 c# windows file-locking

我在Windows中执行文件的文件权限有问题,似乎是在关注论坛提示后解决的[1],但我无法理解为什么.也许你们可以提供帮助.

我正在通过执行它来检查文件的标题(读取控制台输出)然后打开相同的文件以便随后使用FileStream进行读取:

public void fileMD5(string filename) {
  if (!File.Exists(filename)) return NT.Fail("File does not exist: " + filename);

  BinaryReader stream = new BinaryReader(File.Open(filename,
      FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
  int bufferSize = 4096;
  byte[] buffer = new byte[bufferSize];
  int readBytes;
  while ((readBytes = stream.Read(buffer, 0, bufferSize)) > 0) {
    md5Hasher.TransformBlock(buffer, 0, readBytes, buffer, 0);
  }
  stream.Close();
}

fileMD5('sample.exe');
Run Code Online (Sandbox Code Playgroud)

每隔一段时间我就会得到"文件被另一个进程使用".从维基百科我知道Windows将锁定执行拒绝写访问的文件[2],但我只是在阅读.当我尝试打开它时,该过程应该已经停止.

从论坛帖子看,似乎添加一个FileShare.ReadWrite会有所帮助,它似乎确实如此:

FileStream stream = File.Open('sample.exe', 
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Run Code Online (Sandbox Code Playgroud)

但我不明白为什么.这里有没有竞争条件我看不到?

使用FileShare.ReadWrite而不是默认值(我猜是FileShare.Read),File.Open调用似乎要快得多.

[1] http://www.xtremevbtalk.com/archive/index.php/t-192118.html

[2] http://en.wikipedia.org/wiki/File_locking#In_Microsoft_Windows

low*_*wds 9

如果未指定FileShare参数,则此选项的默认值为FileShare.None,实际上File类中的代码只执行以下操作:

public static FileStream Open(string path, FileMode mode, FileAccess access)
{
    return File.Open(path, mode, access, FileShare.None);
}
Run Code Online (Sandbox Code Playgroud)

关于性能,我只能想象指定FileShare.ReadWrite意味着Windows不需要获取文件锁.

如果你在使用块中包含stream变量的使用,那么当你完成时,Stream会被处理掉,如果"另一个进程正在使用该文件"错误,你会得到这个问题吗?

using (var stream = File.Open('sample.exe', FileMode.Open, FileAccess.Read))
{
  //do something with the stream here
}
Run Code Online (Sandbox Code Playgroud)