Salo7ty
Salo7ty

Reputation: 495

Are there any benefits for using SafeFileHandle with FileStream constructor

I read a lot about SafeFileHandle and from what I've seen I think I don't have to use it or it doesn't have any benefits to use it in FileStream because it is closed by first object of file stream handled it and I can't use it in another objects.

Can any one tell me when should I use it?

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();
}

From what I have seen that definition of SafeFileHandle is: it is something like a person hold one hand of a rope and they are playing with children, and every child hold the second hand of rope.

person = file handle or any handle (network connection or anything)

rope = SafeFileHandle

kids = objects that want to make operations with file handle like FileStream

This is my perception about safe file handle, is it correct?

Upvotes: 1

Views: 1468

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70661

The overloads that accept SafeFileHandle exist for the same reason that the now-obsolete overloads that accepted an IntPtr did: so that you can construct a new FileStream instance from a file handle that you obtained through p/invoke interop, i.e. from unmanaged code.

The SafeHandle type and idiom for its use did not exist in the earliest versions of .NET. Raw IntPtr values were used any time managed code needed to deal with native handles. When the much better SafeHandle type was introduced, it simply made sense to provide specific subclasses for commonly-used native handle types, like file handles, and then to support those specific subclasses in any managed API, including constructors like those for FileStream, where the native handle type previously was used.

The example you've provided would never (or at least, should never) appear in real-world code. If you are opening a file from managed code and using it only in managed code, then you just do that. You never have any reason to mess with the native file handle at all. You would use the SafeFileHandle property of a FileStream object only if you needed to pass the native file handle to unmanaged code, and you would pass a SafeFileHandle value to the FileStream constructor only if you had no way to obtain that particular file handle except from unmanaged code.

Frankly, I don't really understand your analogy with the rope and children. It doesn't seem correct or useful to me though. You already got an answer to your previous, very broad question What is SafeFileHandle in c# and when should i use?, so you should already know why SafeFileHandle exists, but to recap here:

  • SafeHandle, and its subclasses, are provided as a much-better alternative to having to make one's class deal with finalizers. The SafeHandle class itself implements the finalization logic, so your class doesn't have do. At least, as long as the only unmanaged objects your class would normally deal with can be wrapped in a SafeHandle subclass — and since you can implement your own wrappers, for those objects that don't already have a .NET-provided wrapper, this should be all of your unmanaged objects — then you don't need a finalizer. (You still need to implement IDisposable, so that your unmanaged objects can be cleaned up deterministically…the finalizer is solely there as a backup).

I hope that the above is sufficient to explain all this. Stack Overflow isn't really the right place for extensive, tutorial level explanations of concepts. But, assuming the above short discussion provides the level of detail you needed to understand why those constructors exist, that seems fine to me.

Upvotes: 3

Related Questions