Есть ли какие-либо преимущества для использования SafeFileHandle с конструктором FileStream - PullRequest
1 голос
/ 27 октября 2019

Я много читал о 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

Это мое восприятие безопасного дескриптора файла,это правильно?

1 Ответ

1 голос
/ 27 октября 2019

Перегрузки, которые принимают SafeFileHandle, существуют по той же причине, что и устаревшие сейчас перегрузки, которые приняли IntPtr: так что вы можете создать новый экземпляр FileStream из дескриптора файла, который вы получили через p /вызвать взаимодействие, т. е. из неуправляемого кода.

Тип SafeHandle и идиома его использования не существовали в ранних версиях .NET. Необработанные значения IntPtr использовались в любое время, когда управлял кодом, необходимым для работы с собственными дескрипторами. Когда был представлен гораздо лучший тип SafeHandle, просто имело смысл предоставить конкретные подклассы для обычно используемых типов собственных дескрипторов, таких как файловые дескрипторы, а затем поддерживать эти конкретные подклассы в любом управляемом API, включая конструкторы, подобные тем, которые используются для * 1009. *, где ранее использовался собственный тип дескриптора.

Приведенный вами пример никогда не будет (или, по крайней мере, никогда) не появится в реальном коде. Если вы открываете файл из управляемого кода и используете его только в управляемом коде, то вы просто делаете это. У вас никогда нет причин возиться с нативным дескриптором файла. Вы бы использовали свойство SafeFileHandle объекта FileStream только в том случае, если вам нужно было передать собственный дескриптор файла неуправляемому коду, и вы бы передали значение SafeFileHandle конструктору FileStream, только если у вас не было возможностиполучить этот конкретный дескриптор файла, кроме как из неуправляемого кода.

Честно говоря, я не совсем понимаю вашу аналогию с веревкой и детьми. Это не кажется правильным или полезным для меня, хотя. Вы уже получили ответ на свой предыдущий, очень широкий вопрос Что такое SafeFileHandle в c # и когда мне следует его использовать? , поэтому вы уже должны знать, почему существует SafeFileHandle, но подведем итог:

  • SafeHandle и его подклассы - гораздо лучшая альтернатива заключению классовой сделки с финализаторами. Класс SafeHandle сам реализует логику финализации, поэтому вашему классу это не нужно. По крайней мере, до тех пор, пока единственные неуправляемые объекты, с которыми обычно работает ваш класс, могут быть заключены в подкласс SafeHandle - и, поскольку вы можете реализовать свои собственные оболочки, для тех объектов, у которых еще нет оболочки, предоставляемой .NETэто должно быть всех ваших неуправляемых объектов - тогда вам не нужен финализатор. (Вам все еще нужно реализовать IDisposable, чтобы ваши неуправляемые объекты могли быть детерминированно очищены ... финализатор находится там исключительно как резервная копия).

Я надеюсь, что вышеприведенного достаточно, чтобы объяснить всеэто. Переполнение стека не совсем подходящее место для подробных объяснений концепций на уровне учебного пособия. Но, если предположить, что вышеупомянутое краткое обсуждение обеспечивает уровень детализации, который вам необходим, чтобы понять, почему существуют эти конструкторы, мне это кажется правильным.

...