web-dev-qa-db-fra.com

L'écriture dans MemoryStream avec StreamWriter renvoie vide

Je ne suis pas sûr de ce que je fais mal, j'ai vu beaucoup d'exemples, mais je n'arrive pas à faire fonctionner cela.

public static Stream Foo()
{
    var memStream = new MemoryStream();
    var streamWriter = new StreamWriter(memStream);

    for (int i = 0; i < 6; i++)
        streamWriter.WriteLine("TEST");

    memStream.Seek(0, SeekOrigin.Begin);
    return memStream;
}

Je fais un test simple sur cette méthode pour essayer de la faire passer, mais quoi qu'il en soit, mon compte de collection est 0.

[Test]
public void TestStreamRowCount()
{
    var stream = Foo();

    using (var reader = new StreamReader(stream))
    {
        var collection = new List<string>();
        string input;

        while ((input = reader.ReadLine()) != null)
            collection.Add(input);

        Assert.AreEqual(6, collection.Count);
    }
}

Remarque: J'ai modifié une syntaxe ci-dessus sans compiler dans la méthode Test. Ce qui est plus important, c'est la première méthode qui semble retourner un flux vide (mon reader.ReadLine () lit toujours une fois). Je ne sais pas ce que je fais mal. Je vous remercie.

26
jsmith

Vous oubliez de vider votre instance StreamWriter.

public static Stream Foo()
{
    var memStream = new MemoryStream();
    var streamWriter = new StreamWriter(memStream);

    for (int i = 0; i < 6; i++)
        streamWriter.WriteLine("TEST");

    streamWriter.Flush();                                   <-- need this
    memStream.Seek(0, SeekOrigin.Begin);
    return memStream;
}

Notez également que StreamWriter est censé être supprimé, car il implémente IDisposable, mais que cela génère à son tour un autre problème, il fermera également le MemoryStream sous-jacent.

Voulez-vous vraiment renvoyer un MemoryStream ici?

Je changerais le code en ceci:

public static byte[] Foo()
{
    using (var memStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memStream))
    {
        for (int i = 0; i < 6; i++)
            streamWriter.WriteLine("TEST");

        streamWriter.Flush();
        return memStream.ToArray();
    }
}

[Test]
public void TestStreamRowCount()
{
    var bytes = Foo();

    using (var stream = new MemoryStream(bytes))
    using (var reader = new StreamReader(stream))
    {
        var collection = new List<string>();
        string input;

        while ((input = reader.ReadLine()) != null)
            collection.Add(input);

        Assert.AreEqual(6, collection.Count);
    }
}

Puisque vous n'utilisez pas "using" ou streamWriter.Flush (), le rédacteur n'a pas validé les modifications du flux. En conséquence, Stream itslef ne dispose pas encore de données. En général, vous souhaitez encapsuler la manipulation avec les instances Stream et StremaWriter avec using.

Vous devriez également envisager de renvoyer une nouvelle instance de MemoryStream:

using(var memStream = new MemoryStream())
{
   ....
   return new MemoryStream(memStream.ToArray(), false /*writable*/);
}
12
Alexei Levenkov

Essayez de vider streamWriter après avoir écrit vos lignes.

4