C# 已删除文件的行为是否使用FileShare打开。是否在Windows上删除更改?

C# 已删除文件的行为是否使用FileShare打开。是否在Windows上删除更改?,c#,windows,filesystems,C#,Windows,Filesystems,我们已经使用以下代码好几年了 /// <summary> /// Opens a file and returns an exclusive handle. The file is deleted as soon as the handle is released. /// </summary> /// <param name="path">The name of the file to create</param>

我们已经使用以下代码好几年了

    /// <summary>
    /// Opens a file and returns an exclusive handle. The file is deleted as soon as the handle is released.
    /// </summary>
    /// <param name="path">The name of the file to create</param>
    /// <returns>A FileStream backed by an exclusive handle</returns>
    /// <remarks>If another process attempts to open this file, they will recieve an UnauthorizedAccessException</remarks>
    public static System.IO.FileStream OpenAsLock(string path)
    {
        var stream = TranslateIOExceptions(() => System.IO.File.Open(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.Delete));
        System.IO.File.Delete(path);
        return stream;
    }
不幸的是,我们的单元测试可能捕捉到了这种行为变化,但它没有正确配置为在我们的环境中每晚运行,所以我不能确定它是否运行过绿色


这真的是行为上的改变吗?我们知道什么时候发生的吗?这是有意的(有记录的)?

非常感谢Eryk提供的提示

事实证明,我们确实有几个单元测试可以捕捉到这种行为变化,包括显式测试这种行为的测试。我怀疑这些是在一开始调查这种奇怪行为时添加的

单元测试还没有发出警报,因为我们的测试机器运行的是比我的开发机器旧的Windows 10版本

  • 构建17134.1304肯定有旧的行为
  • Build 18363.657肯定有新的行为
我查看了,不幸的是,这两个版本之间有二十多个版本。然而,我非常怀疑这个“改进和修复”被列为

解决存储在群集中的文件共享的问题 具有备用数据流的卷(CSV)仍然存在 尝试删除它们。您还可能会收到“访问被拒绝”消息 下次尝试访问或删除文件

我不确定CSV特定的更改为什么会影响我的系统,但描述与我看到的更改完全匹配


关于特定的代码,我们的代码中从未使用过返回“FileStream”。相反,我们依赖IDisposable接口,在“关键部分”完成时关闭流,并解锁共享文件

从技术上讲,这是一个突破性的变化,我现在做以下几点:

  • 使用独占句柄创建锁文件
  • 返回实现IDisposable的新对象
  • 等待一次性对象被释放,然后关闭流并尝试删除文件

  • 在最近发布的Windows 10中,这种行为发生了变化——AFAIK未经通知
    DeleteFileW
    如果文件系统支持,现在尝试使用它。NTFS有。使用POSIX语义设置删除配置后,只要
    DeleteFileW
    关闭其句柄,文件就会被取消链接。必须具有共享删除访问权限的现有打开可以继续访问该文件,但它们无法取消删除配置,这与经典的Windows删除语义不同。如果您想要在关闭最后一个句柄之前将文件链接到目录中的经典行为,您可以手动调用
    SetFileInformationByHandle
    FileDispositionInfo
    。让我重申一下,现有的open必须共享delete访问权限才能删除或重命名文件,而不管删除语义如何,因此Windows与POSIX系统仍然有很大的不同。大多数应用程序在其打开的文件上共享读/执行和写/附加访问权限,但它们不共享删除/重命名访问权限。@ErykSun,您知道哪个Windows 10版本和内部版本使删除同步,以及对应的Windows Server版本吗?eisenpony的回答建议版本为
    1909
    ,构建为
    18363.657
    ,但用户刚刚评论说,他们仍然可以看到截至
    18363.1316
    的异步行为。
    class Program
    {
        static void Main(string[] args)
        {
            File.Open("test", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Delete);
            File.Delete("test");
            File.WriteAllText("test", "hello world");
            Console.Write(File.ReadAllText("test"));
            Console.ReadLine();
        }
    }
    
    // ...
        public static IDisposable OpenAsLock(string path)
        {
            var stream = TranslateIOExceptions(() => System.IO.File.Open(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None));
            return new FileBasedLock(stream, path);
        }
    // ...
    
    internal class FileBasedLock : IDisposable
    {
        public FileBasedLock(FileStream stream, string path)
        {
            Stream = stream ?? throw new System.ArgumentNullException(nameof(stream));
            Path = path ?? throw new System.ArgumentNullException(nameof(path));
        }
    
        public FileStream Stream { get; }
        public string Path { get; }
        public void Dispose()
        {
            Stream.Close();
            try { File.Delete(Path); }
            catch (IOException) { }
        }
    }