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

时间:2011-08-10 08:09:03

标签: 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');

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

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

FileStream stream = File.Open('sample.exe', 
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

但我不明白为什么。这里有竞争条件,我看不到吗?

使用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

4 个答案:

答案 0 :(得分:8)

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

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

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

如果您在使用块中包含stream变量的使用,那么当您使用Stream时,如果“另一个进程正在使用该文件”错误,则此问题会消失做什么?

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

答案 1 :(得分:2)

您应该关闭FileStream,然后再打开一个新的FileStream。

当应用程序想要共享文件时,不仅需要一个应用程序,或者一个应用程序同时拥有多个读者或编写者,也需要FileShare。

为什么呢?当每个人都可以同时阅读和写作时,它会变得混乱。在这种情况下,你应该更明确地设置它,以便它变得凌乱。 :)

答案 2 :(得分:1)

它与底层的Windows API CreateFile标志有关。 见http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx 概述, http://blogs.msdn.com/b/larryosterman/archive/2004/05/13/131263.aspx 解释NT(和以下)如何使用FILE_SHARE_DELETE

加载执行程序

特别是这个

http://blogs.msdn.com/b/oldnewthing/archive/2004/05/11/129759.aspx

有关共享权限和所需访问权限如何组合的详细解释!

答案 3 :(得分:0)

似乎指定错误的FileShare可能会禁止您访问文件。如果指定FileShare.Read但某些其他应用程序当前具有该文件的写入权限,则无法访问该文件,因为您的FileShare.Read当前不可满足。 FileShare.ReadWrite限制性较小,因为它更容易满足。资料来源:http://blogs.msdn.com/b/oldnewthing/archive/2004/05/11/129759.aspx