Есть ли преимущества использования 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
Это мое мнение о безопасном обращении с файлами, это правильно?
1 ответ
Перегрузки, которые принимают SafeFileHandle
существуют по той же причине, что и устаревшие перегрузки, которые принимали IntPtr
сделал: чтобы вы могли построить новый FileStream
экземпляр из дескриптора файла, который вы получили через взаимодействие p/invoke, то есть из неуправляемого кода.
В SafeHandle
тип и идиома для его использования не существовали в самых ранних версиях.NET. СырьеIntPtr
значения использовались в любое время, когда управляемый код необходим для работы с собственными дескрипторами. Когда намного лучшеSafeHandle
type, просто имело смысл предоставить определенные подклассы для обычно используемых типов собственных дескрипторов, таких как дескрипторы файлов, а затем поддерживать эти конкретные подклассы в любом управляемом API, включая конструкторы, подобные конструкторам для FileStream
, где ранее использовался собственный тип дескриптора.
Приведенный вами пример никогда (или, по крайней мере, никогда не должен) появиться в реальном коде. Если вы открываете файл из управляемого кода и используете его только в управляемом коде, вы просто делаете это. У вас вообще никогда не будет причин возиться с собственным дескриптором файла. Вы бы использовалиSafeFileHandle
собственность FileStream
объект только в том случае, если вам нужно передать собственный дескриптор файла в неуправляемый код, и вы должны передать SafeFileHandle
ценность для FileStream
конструктор, только если у вас не было возможности получить этот конкретный дескриптор файла, кроме как из неуправляемого кода.
Честно говоря, я не очень понимаю вашу аналогию с веревкой и детьми. Однако мне это не кажется правильным или полезным. Вы уже получили ответ на свой предыдущий очень широкий вопрос: что такое SafeFileHandle в C# и когда мне следует использовать?, так что вы уже должны знать, почемуSafeFileHandle
существует, но резюмируем здесь:
SafeHandle
, и его подклассы, предоставляются как гораздо лучшая альтернатива тому, чтобы иметь дело с классом финализаторов. ВSafeHandle
Сам класс реализует логику финализации, поэтому вашему классу это не нужно. По крайней мере, до тех пор, пока единственные неуправляемые объекты, с которыми обычно имеет дело ваш класс, могут быть заключены вSafeHandle
подкласс - и поскольку вы можете реализовать свои собственные оболочки, для тех объектов, которые еще не имеют оболочки, предоставляемой.NET, это должны быть все ваши неуправляемые объекты - тогда вам не нужен финализатор. (Вам все еще нужно реализоватьIDisposable
, так что ваши неуправляемые объекты могут быть очищены детерминированным образом... финализатор существует исключительно как резервная копия).
Я надеюсь, что вышеизложенного достаточно, чтобы все это объяснить. stackru - не самое подходящее место для подробных объяснений концепций на уровне учебника. Но если предположить, что приведенное выше краткое обсуждение обеспечивает уровень детализации, необходимый для понимания того, почему существуют эти конструкторы, мне это кажется нормальным.