Не утилизируете поток streamreader закрыть поток?



Я посылаю поток в методы для записи, и в этих методах я использую двоичный reader/wrtier. Когда читатель / писатель будет удален, либо по using или просто когда на него не ссылаться, это поток закрыт??



Я бы отправил BinaryReader / Writer, но я тоже использую StreamReader (возможно, я должен обойти это. Я использую это только для GetLine и ReadLine). Это довольно хлопотно, если он закрывает поток каждый раз, когда писатель/читатель получает закрытый.

651   7  

7 ответов:

да StreamReader,StreamWriter,BinaryReader и BinaryWriter все закрывают / утилизируют свои базовые потоки при вызове Dispose на них. Они не утилизируйте поток, если читатель / писатель просто мусор, хотя-вы всегда должны утилизировать читателя / писателя, предпочтительно с using заявление. (Фактически, ни один из этих классов не имеет финализаторов и не должен иметь.)

лично я предпочитаю иметь оператор using для потока. Вы можете гнездо using высказывания без скобок довольно аккуратно:

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

даже если using оператор для потока несколько избыточен (если только StreamReader конструктор бросает исключение) я считаю это лучшей практикой, как тогда, если вы избавитесь от StreamReader и просто используйте поток непосредственно на более поздний срок, вы уже будете иметь правильную семантику утилизации.

Это старый, но я хотел сделать что-то подобное сегодня и обнаружил, что все изменилось. Начиная с .net 4.5, есть :

public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )

единственная проблема заключается в том, что не вполне очевидно, что для других параметров. Вот некоторые справки:

С страница msdn для StreamReader конструктор (поток):

этот конструктор инициализирует кодировку в UTF8Encoding, Свойство BaseStream с использованием параметра stream и внутреннего размер буфера до 1024 байт.

остается detectEncodingFromByteOrderMarks, которые судя по исходный код и true

public StreamReader(Stream stream)
        : this(stream, true) {
}

public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
        : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}

было бы неплохо, если бы некоторые из этих значений по умолчанию были выставлены или если бы аргументы были необязательными, чтобы мы могли просто указать те, которые мы хотим.

Да, это делает. Вы можете проверить это, посмотрев на реализацию с отражателем.

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {    
            this.stream = null;    
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}

шесть лет спустя, но, возможно, это может помочь кому-то.

StreamReader закрывает соединение при его удалении. Однако, " используя (Stream stream = ...) {...} "с StreamReader / StreamWriter может привести к тому, что поток будет удален дважды: (1) когда объект StreamReader будет удален (2) и когда поток, использующий блок, закроется. Это приводит к предупреждению CA2202 при запуске анализа кода VS.

другое решение, взятое непосредственно из CA2202 страница, должна использовать блок try / finally. Установите правильно, это только закроет соединение один раз.

в нижней части CA2202, Microsoft рекомендует использовать следующее:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

вместо...

// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
    // Use the reader object...
}

да. Вызов Dispose () on и IDisposable (который" использует") должен заставить объект очистить все его ресурсы. Это включает в себя потоки промывки и закрытия их файловые дескрипторы.

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

простой способ исправить это, если вам нужно, чтобы переопределить StreamWriter классы Dispose метод. Смотрите мой пост здесь для кода о том, как это сделать:

делает .Расправившись с помощью StreamWriter закрыть основной поток?

поток, расположенный либо с помощью ключевого слова" using", либо вызывая dispose явно

Comments

    Ничего не найдено.