2011-04-13 141 views
23

我不確定我在做什麼錯誤,看過很多示例,但似乎無法得到此工作。使用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方法中編譯。更重要的是第一個方法似乎是返回一個空的流(我的reader.ReadLine()總是讀取一次)。不知道我做錯了什麼。謝謝。

回答

49

您忘記刷新您的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; 
} 

還要注意的是StreamWriter應該被設置的,因爲它實現IDisposable,但這又產生了另一個問題,它會關閉底層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); 
    } 
} 
+3

我不同意將其轉換爲一個數組。一個MemoryStream可以作爲普通的Stream,大多數時候它的消費者並不關心它的實現。很多時候在生產期間使用MemoryStream進行測試和生成文件流時,例如 – 2011-04-13 17:22:23

+1

出於我的目的,我確實想要返回Stream。出於同樣的原因馬特上面提到。沖洗StreamWriter是我錯過了。謝謝。 – jsmith 2011-04-13 17:33:11

+0

我知道這是一個古老的帖子。但它救了我。謝謝:) – Andrew 2017-05-22 11:36:50

4

試着寫你的線條後沖洗的StreamWriter。

+1

沖洗流幫助我!只是一個側面說明;我正在使用流寫入器向存儲器流寫入1348個字節。 1024字節會寫(無需刷新),並花了我很長時間才弄清楚,但最終刷新它移動了其他324字節。 – Dave 2015-07-17 14:36:24

11

由於您沒有使用「using」或streamWriter.Flush(),因此作者沒有對流提交更改。結果Stream itslef還沒有數據。一般而言,您希望使用Stream和StremaWriter實例來處理操作。

您還應該考慮的MemoryStream的返回新實例:

using(var memStream = new MemoryStream()) 
{ 
    .... 
    return new MemoryStream(memStream.ToArray(), false /*writable*/); 
} 
+0

你爲什麼要返回一個新的MemoryStream實例?這不是低效率,多餘? – jsmith 2011-04-13 17:45:10

+4

爲了使其只讀,停止使用分配給可寫入流的額外內存,以允許在創建流時創建正常的流代碼模式。在這種特殊情況下,它並不是非常重要,但是如果返回的數據流將被關閉或更改,那麼返回的數據流通常可以很好地返回給調用方。在這種特殊情況下,您可以通過使用GetBuffer而不是ToArray(它使內部緩衝區的副本)非常高效地創建新的流。 – 2011-04-13 18:24:09