Как избавиться от File.OpenRead () - PullRequest
4 голосов
/ 28 марта 2011

Как правильно распоряжаться File.OpenRead (). Я сейчас использую код ниже?

using (BinaryReader br = new BinaryReader(File.OpenRead(path)))
{
   myByte = br.ReadByte();
}

При анализе кода я получаю в Visual Studio следующее:

Предупреждение 1 CA2000: Microsoft.Надежность: в методе 'Program.Main (string [])', объект File.OpenRead (путь) не расположен вдоль всех путей исключения. Вызов System.IDisposable.Dispose на объекте File.OpenRead (путь) перед всеми ссылки на него выходят за рамки.

Ответы [ 4 ]

16 голосов
/ 28 марта 2011

На первый взгляд это выглядит как ложный положительный результат, потому что удаление BinaryReader также избавит от FileStream, возвращаемого File.OpenRead:

От: http://msdn.microsoft.com/en-us/library/azy2k2bx.aspx

Если параметр распоряжения имеет значение true, этот метод освобождает все ресурсы, удерживаемые любыми управляемыми объектами, на которые ссылается этот BinaryReader.Этот метод вызывает метод Dispose для каждого объекта, на который есть ссылка.

Однако существует один угловой случай, когда FileStream действительно не удаляется: когда конструктор BinaryReader выдает исключение!

Решение:
Правильный способ написания вашего кода будет выглядеть следующим образом:

using (var fs = File.OpenRead(path))
{
    BinaryReader br = new BinaryReader(fs);
    myByte = br.ReadByte();
}

Справочная информация:
BinaryReader содержит только ссылку наFileStream и, следовательно, не нуждается в утилизации.
Code Analysis разделяет это мнение.


Кстати: при использовании этого решения для потока с возможностью записи важно очистить устройство записиперед удалением потока:

using (var fileStream = new FileStream(...))
{
    var writer = new StreamWriter(fileStream);

    writer.WriteLine(...);

    writer.Flush(); // <-- Important
}

Если вы забудете об этом, ваш поток может не содержать всего, что было написано с использованием StreamWriter.

3 голосов
/ 28 марта 2011

Как насчет:

using (Filestream fs = File.OpenRead(Path))
{
    using (BinaryReader br = new BinaryReader(fs))
    {
        myByte = br.ReadByte();
    }
}
0 голосов
/ 28 марта 2011

Как FileStream, созданный File.OpenRead, так и BinaryReader, который вы создаете для этого FileStream, должны быть утилизированы, поэтому вам нужна явная ссылка на каждый из них:

using(FileStream fs = File.OpenRead(path))
using(BinaryReader br = new BinaryReader(fs))
{
   myByte = br.ReadByte();
}
0 голосов
/ 28 марта 2011

File.OpenRead возвращает FileStream, который также IDisposible.Вы можете поместить его во внешний блок using, если хотите, или объявить его и удалить за пределами текущего использования.

...