2015-04-15 4 views
-2

Я недавно наткнулся на this post, где отмеченный ответ Jon Skeet. В ней он объясняет различные способы создания пустого файла, такие как:File.Create queries

using (File.Create(filename)) ; 

using (File.Create(filename)) {} 

File.Create(filename).Dispose(); 

и затем есть еще один способ, которым люди рекомендуют использовать:

File.Create(filename).Close(); 

Теперь ответ Джона идет в какую-то деталь о том, какой из них использовать и почему и т. д. Но ответ устарел/старый, и не так много деталей, как хотелось бы, о котором лучше было бы обеспечить закрытие файла и почему.

+1

Я вроде как один из других ответов, используя 'File.WriteAllText' с пустой строкой.Он может быть * чуть менее эффективен под капотом, но он оставляет доступ к рамочному коду, а не требует явного или какого-либо обмана. (Если бы я увидел, что «использование» блочного подхода в производственном коде может потребовать двойного взлома, чтобы полностью его проверить. Возможно, это будет немного более эффективным, но такие двойные попытки могут привести к недоразумениям поведения кода и будущих ошибок.) – David

+0

Да, это основная причина этого, потому что я нашел этот код в унаследованном проекте и изучал его. Однако сам я считаю, что метод WriteAllText в этом случае более запутан. – TheLethalCoder

+0

Лучшее предложение Джона обертывает все это по точно названному методу. Запускайте тесты производительности, тесты условий гонки и т. Д. Все после факта, чтобы настроить на байт по мере необходимости (при необходимости вообще). Но пока функциональность существует в одном абстрагированном месте с хорошим именем, тогда остальная часть производственного кода, который ее использует, будет понятной и понятной. – David

ответ

2

Ответ определенно не устарел. Возможно, вы проверили небольшое исследование фактической реализации метода FileStream.Dispose в общедоступной ссылке source code, что метод DisposeFileStream выполнит вызов handle.Dispose и выполнит ряд других действий.

Класс FileStream не переопределяет реализацию виртуального метода Stream.Close(), реализованного в его базовом классе. Этот базовый класс в настоящее время просто вызовет виртуальный Dispose(true) и, таким образом, приведет к тому же пути.

Как упомянуто в документации по методу Close:

Этот метод вызывает Dispose, указав верный освободить все ресурсы. Вам не нужно специально вызывать метод Close. Вместо этого обеспечьте , что каждый объект Stream правильно расположен. Вы можете объявить объекты Stream в используемом блоке (или с использованием блока в Visual Basic) до убедиться, что поток и все его ресурсы расположены, или вы, , можете явно вызвать метод Dispose.

Тем не менее, вы должны всегда вызывать Dispose, когда вы работаете с IDisposable, например, как он мог (в настоящее время или в какой-то момент в будущем) держать другие внутренние ресурсы, кроме дескриптора файла, который будет не будет выпущен, если вы только назовете Close на примере FileStream.

При этом статический способ создания файла, такой как File.WriteAllBytes или File.WriteAllText, который обеспечивает надлежащее удаление, также будет работать. Но, по-моему, они чувствуют себя неловко и не выражают намерения так хорошо.

Обертка это статическим методом, называемым CreateEmptyFile, или статическим классом EmptyFile с единственным методом Create, как это предлагается в исходном ответе, и в нем четко указывается, что вы намерены делать.

Это следует понимать как любой прямой вызов Dispose или (предпочтительно) путем обертывания ресурса в using блоке.

+0

Я понимаю это, но не всегда ли вероятность того, что вызов Dispose не будет вызван? Так следует ли всегда использовать использование в этом случае? Как бы странно это ни выглядело? – TheLethalCoder

+0

На мой взгляд, если вы запрашиваете одноразовый экземпляр, вызывая метод в каком-то классе, вы несете ответственность за вызов 'Dispose' на него. – Alex

+0

Ответственный да, но разве нет шанса, что самоназванное распоряжение фактически не будет вызвано? Скажите, например, в многопоточной ситуации? – TheLethalCoder