web-dev-qa-db-fra.com

MemoryStream - Impossible d'accéder à un flux fermé

Bonjour pourquoi using (var sw = new StreamWriter(ms)) retourne Cannot access a closed Streamexception. Memory Stream est au-dessus de ce code.

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
}

Quelle est la meilleure façon de le réparer? Merci

51
Arbejdsglæde

Ceci est dû au fait que StreamReader ferme automatiquement le flux sous-jacent lors de son élimination. L'instruction using le fait automatiquement.

Cependant, le StreamWriter que vous utilisez essaie toujours de travailler sur le flux (de plus, l'instruction using de l'écrivain essaie maintenant de disposer du StreamWriter, qui tente alors de fermer le flux).

La meilleure façon de résoudre ce problème est de ne pas utiliser using et de ne pas disposer de StreamReader et StreamWriter. Voir cette question .

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());                        
}

Si vous vous sentez mal à propos de sw et sr d'être collectés sans être éliminés dans votre code (comme recommandé), vous pouvez procéder de la manière suivante:

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();
}
79
Thorsten Dittmar

Depuis .net45, vous pouvez utiliser l'argument de constructeur LeaveOpen de StreamWriter et continuer à utiliser l'instruction using.

using (var ms = new MemoryStream())
{
    using (var sw = new StreamWriter(ms, Encoding.UTF8, 1024, true))
    {
        sw.WriteLine("data");
        sw.WriteLine("data 2");    
    }

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

Lorsque using () pour votre StreamReader se termine, il supprime l'objet et ferme le flux que votre StreamWriter tente toujours d'utiliser.

5
itsme86

quand il sort de l'instruction using, la méthode Dispose sera appelée automatiquement pour fermer le flux

essayez ce qui suit:

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());
        }
}    
1

Le problème est ce bloc:

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

Lorsque StreamReader est fermé (après avoir quitté l'utilisation), il ferme également son flux sous-jacent. Le MemoryStream est donc fermé. Lorsque le StreamWriter se ferme, il essaie de tout vider vers le MemoryStream, mais il est fermé.

Vous devriez envisager de ne pas mettre le StreamReader dans un bloc using.

1
vcsjones

Dans mon cas (certes très mystérieux et peu susceptible d’être reproduit souvent), cela était à l’origine du problème (ce code est lié à la génération PDF utilisant iTextSharp):

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

La déclaration d’un tableau à 3 cellules/colonnes, puis la définition de deux valeurs seulement pour la largeur sont apparemment à l’origine du problème. Une fois que j'ai remplacé "PdfPTable (3)" par "PdfPTable (2)", le problème est apparu comme celui du four à convection.

0
B. Clay Shannon