我在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
答案 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