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

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

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

7 ответов


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

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

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

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


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

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

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

С в MSDN в разделе для конструктора StreamReader (Stream):

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

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

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

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

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


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

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.


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

делает .Удаление StreamWriter закрыть основной поток?


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