Подтвердить что ты не робот

MemoryStream - невозможно получить доступ к закрытому потоку

Привет, почему using (var sw = new StreamWriter(ms)) возвращает Cannot access a closed Stream exception. Memory Stream находится поверх этого кода.

using (var ms = new MemoryStream())
{
    using (var sw = new StreamWriter(ms))
    {                 
        sw.WriteLine("data");
        sw.WriteLine("data 2");
        ms.Position = 0;
        using (var sr = new StreamReader(ms))
        {
            Console.WriteLine(sr.ReadToEnd());                        
        }
    } //error here
}

Какой лучший способ это исправить? Спасибо

4b9b3361

Ответ 1

Это связано с тем, что StreamReader автоматически закрывает базовый поток при его удалении. Оператор using делает это автоматически.

Однако используемый вами StreamWriter по-прежнему пытается работать с потоком (также оператор using для автора теперь пытается избавиться от StreamWriter, который затем пытается закрыть поток).

Лучший способ исправить это: не используйте using и не удаляйте StreamReader и StreamWriter. См. этот вопрос.

using (var ms = new MemoryStream())
{
    var sw = new StreamWriter(ms);
    var sr = new StreamReader(ms);

    sw.WriteLine("data");
    sw.WriteLine("data 2");
    ms.Position = 0;

    Console.WriteLine(sr.ReadToEnd());                        
}

Если вы плохо себя чувствуете в sw и sr, будучи собраны в мусор, не будучи удалены в вашем коде (как рекомендовано), вы можете сделать что-то вроде этого:

StreamWriter sw = null;
StreamReader sr = null;

try
{
    using (var ms = new MemoryStream())
    {
        sw = new StreamWriter(ms);
        sr = new StreamReader(ms);

        sw.WriteLine("data");
        sw.WriteLine("data 2");
        ms.Position = 0;

        Console.WriteLine(sr.ReadToEnd());                        
    }
}
finally
{
    if (sw != null) sw.Dispose();
    if (sr != null) sr.Dispose();
}

Ответ 2

Когда использование() для вашего StreamReader завершается, оно удаляет объект и закрывает поток, который ваш StreamWriter все еще пытается использовать.

Ответ 3

В моем случае (по общему признанию, очень загадочном и вряд ли можно часто воспроизводить) это вызывало проблему (этот код связан с созданием PDF с использованием iTextSharp):

PdfPTable tblDuckbilledPlatypi = new PdfPTable(3);
float[] DuckbilledPlatypiRowWidths = new float[] { 42f, 76f };
tblDuckbilledPlatypi.SetWidths(DuckbilledPlatypiRowWidths);

Объявление таблицы с 3 ячейками/столбцами, а затем установление только двух валов для ширины было причиной, по-видимому, проблемы. Как только я изменил "PdfPTable (3)" на "PdfPTable (2)", проблема пошла по пути конвекционной печи.

Ответ 4

когда он выйдет из оператора using, будет вызван метод Dispose, автоматически закрывающий поток

попробуйте следующее:

using (var ms = new MemoryStream())
{
    var sw = new StreamWriter(ms);

        sw.WriteLine("data");
        sw.WriteLine("data 2");
        ms.Position = 0;
        using (var sr = new StreamReader(ms))
        {
            Console.WriteLine(sr.ReadToEnd());
        }
}    

Ответ 5

Проблема заключается в этом блоке:

using (var sr = new StreamReader(ms))
{
    Console.WriteLine(sr.ReadToEnd());                        
}

Когда StreamReader закрывается (после выхода из использования), он также закрывает его под потоком, поэтому теперь MemoryStream закрывается. Когда StreamWriter закрывается, он пытается сбросить все на MemoryStream, но закрыт.

Вы не должны ставить StreamReader в используемый блок.