【发布时间】:2014-11-03 23:42:40
【问题描述】:
我最近注意到FileStream.Lock(long, long) 在.NET 4.0 和.NET 4.5 中记录为保留独占该“进程”对文件指定范围的访问(但实际上是针对该 FileStream 实例或者更确切地说,对于它在内部引用的实际操作系统文件句柄)。另一方面,.NET 2.0 和 3.0 的文档表明其行为是阻止其他人更改文件(不写入该范围 - 即使是当前的 FileStream/句柄,我认为,虽然没有指出)同时 允许所有打开的 FileStreams/句柄的读取访问(假设 ShareMode 允许这样的重叠句柄)。 .NET 3.5 的文档将措辞更改为“防止其他人更改”(无法写入范围);这可能是对行为解释的更正或澄清,或者它可能是一个过渡文档,任何一种行为都可以真正满足(因为它没有指定其他人是否允许读取)而不指定其他访问或重叠锁将被允许或失败。
我以为我之前在 .NET 2.0 中尝试过这个 API,并确认了即使通过锁定 FileStream 也锁定了对锁定范围的写入,但那是几年前的事了,我的回忆可能有问题...... . 我当时可能只是简单地依赖文档,但我觉得我记得实际进行过实验,因为我想确保了解它实际上是如何工作的,并且因为文档在某些方面相当模糊。但是,Google 确实在另一个站点上找到了 this thread from 2007,这似乎表明 LockFile 并没有像人们期望的那样阻止读取访问,最终在底层操作系统中支持“独占访问”锁。
但是,最近在面向 .NET 4.0 和 .NET 2.0 的测试应用程序中进行的实验(在运行 Windows 7 的 64 位计算机上)发现两者都显示出相同的独占行为,如documentation for .NET 4.0。我无法确认 originally documented for .NET 2.0 的行为,我想我记得它过去的行为。
.NET 2.0 框架上的反编译器显示FileStream.Lock(long, long) 调用了 WINAPI 方法LockFile,然后进入 .NET 4.0 框架发现它也从那里调用了相同的 WINAPI 方法。在我找到的文档中,这种 WINAPI 方法被记录为保留“独占访问”。之前是否记录为保留共享只读访问权限?当 .NET 2.0 首次发布时(尤其是在 Windows XP 上),它以前是否具有共享只读访问权限?它的行为是否可能在 Windows Vista 或 Windows 7 上更改为独占访问,或者它是否总是按照 here 记录的那样进行独占访问?
另一方面,WINAPI 方法LockFileEx 采用dwFlags 参数,该参数可以指定指定范围的共享(可能是只读)或排他锁定。 FileStream.Lock(long, long) 方法是否在某个时候被 .NET 2.0 框架的补丁更改了,还是一直使用 LockFile?
不幸的是,.NET 没有提供 FileStream.Lock() 的重载(或我发现的任何其他 API)来访问这种可选择的文件锁定行为,似乎也没有任何其他方法可以使用从FileStream.Lock(long, long) 本身使用的那个——当然除了通过 pInvoke 破解对 WINAPI 方法本身的调用......这对于某些项目是不允许的。
我希望有人能更明确地记住 FileStream.Lock(long, long) 方法和/或它显然调用的底层 WINAPI 方法 LockFile 的实际行为(至少在最新版本中) .NET 2.0 和 .NET 4.x) 或可能知道这些方法的历史,如果它们改变了它们的实际行为,记录的行为似乎在 .NET 2.0 和 .NET 4.0 之间发生变化,并且可以清除这些明显的不一致.
【问题讨论】:
标签: .net winapi file-locking