web-dev-qa-db-ja.com

StreamWriterでMemoryStreamに書き込むと空が返される

私は何が間違っているのかわかりませんが、多くの例を見てきましたが、これを機能させることができないようです。

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

このメソッドで簡単なテストを行って合格するようにしていますが、コレクションのカウントは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);
    }
}

注:Testメソッドでコンパイルせずに、上記の構文をいくつか変更しました。さらに重要なのは、空のストリームを返すように見える最初のメソッドです(my reader.ReadLine()は常に1回読み取ります)。私が何を間違っているのかわからない。ありがとうございました。

26
jsmith

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

また、StreamWriterIDisposableを実装しているため、破棄されることになっていますが、その結果、別の問題が発生し、基になるMemoryStreamも閉じられます。

ここでMemoryStreamを返してよろしいですか?

私はコードをこれに変更します:

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

「using」またはstreamWriter.Flush()を使用していないため、ライターは変更をストリームにコミットしませんでした。その結果、Stream itslefにはまだデータがありません。一般に、StreamインスタンスとStremaWriterインスタンスを使用して操作をラップする必要があります。

また、MemoryStreamの新しいインスタンスを返すことも検討する必要があります。

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

行を書き込んだ後、streamWriterをフラッシュしてみてください。

4