首页 > 解决方案 > 将 SafeFileHandle 与 FileStream 构造函数一起使用有什么好处吗

问题描述

我读了很多关于SafeFileHandle我所看到的内容,我认为我不必使用它,或者使用它没有任何好处,FileStream因为它被处理它的文件流的第一个对象关闭,我可以'不要在其他对象中使用它。

谁能告诉我什么时候应该使用它?

static void Main(string[] args)
{

    string path = "Hello";

    SafeFileHandle handle = File.Open(path, FileMode.OpenOrCreate).SafeFileHandle;

    using (FileStream fs = new FileStream(handle, FileAccess.ReadWrite))
    {
        // do work
    }
        Console.ReadKey();
}

从我所看到的定义SafeFileHandle是:就像一个人握着一根绳子,他们正在和孩子们玩耍,每个孩子都握着另一只手的绳子。

person = 文件句柄或任何句柄(网络连接或任何东西)

绳子=SafeFileHandle

kids = 想要使用文件句柄进行操作的对象,例如FileStream

这是我对安全文件句柄的看法,对吗?

标签: c#handlesafefilehandle

解决方案


接受的重载的SafeFileHandle存在原因与接受 an 的现已过时的重载相同:因此,您可以从通过 p/invoke 互操作获得的文件句柄(即非托管代码)IntPtr构造新实例。FileStream

SafeHandle.NET 的最早版本中不存在其使用的类型和习语。原始IntPtr值用于任何需要处理本机句柄的托管代码。当引入更好的SafeHandle类型时,为常用的本机句柄类型(如文件句柄)提供特定的子类,然后在任何托管 API 中支持这些特定的子类,包括像 for 的构造函数FileStream,其中本机句柄以前使用的类型。

您提供的示例永远不会(或至少不应该)出现在实际代码中。如果您从托管代码打开文件并仅在托管代码中使用它,那么您只需执行此操作。您根本没有任何理由弄乱本机文件句柄。仅当您需要将本机文件句柄传递给非托管代码时才使用对象的SafeFileHandle属性,并且仅当您无法从非托管代码中获取该特定文件句柄时才将值传递给构造函数。FileStreamSafeFileHandleFileStream

坦率地说,我真的不明白你用绳子和孩子做的类比。不过,这对我来说似乎并不正确或有用。您已经回答了您之前的非常广泛的问题什么是 c# 中的 SafeFileHandle 以及我应该何时使用?,所以你应该已经知道为什么SafeFileHandle存在,但在这里回顾一下:

  • SafeHandle及其子类提供了一个更好的替代方案,而不是让一个类处理终结器。该类SafeHandle本身实现了终结逻辑,因此您的类没有做。至少,只要您的类通常处理的唯一非托管对象可以包装在SafeHandle子类中——而且由于您可以实现自己的包装器,对于那些还没有 .NET 提供的包装器的对象,这应该成为你所有的非托管对象——那么你就不需要终结器了。(您仍然需要实现IDisposable,以便可以确定地清理您的非托管对象......终结器仅作为备份存在)。

我希望以上内容足以解释这一切。Stack Overflow 并不是对概念进行广泛的、教程级别的解释的正确位置。但是,假设上面的简短讨论提供了您理解这些构造函数存在的原因所需的详细程度,这对我来说似乎很好。


推荐阅读