2011-04-13 4 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 인스턴스를 플러시하는 것을 잊어 버리고 있습니다. 이 IDisposable을 구현하지만 차례로 그 또 다른 문제를 발생하기 때문에

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가 처리하도록되어 있습니다, 그것은뿐만 아니라 기본 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은 단순한 스트림으로 작동 할 수 있으며, 대부분의 경우 소비자는 자신의 구현을 신경 쓰지 않습니다. 예를 들어 –

+1

과 같이 테스트하는 동안 MemoryStream을 사용하고 제작 중에 파일 스트림을 사용하는 경우가 많습니다. 제 목적 상 스트림을 반환하려고합니다. 위에서 언급 한 매트와 같은 이유 때문입니다. StreamWriter를 비우는 것은 제가 빠뜨린 것입니다. 고맙습니다. – jsmith

+0

나는 이것이 고대의 지위임을 안다. 하지만 방금 날 구해 줬어. 감사합니다 :) – Andrew

4

당신의 라인을 작성 후 StreamWriter를 플러싱보십시오.

+1

스트림 플러시 날 도와 줬어! 그냥 사이드 노트; 스트림 라이터를 사용하여 메모리 스트림에 1348 바이트를 쓰고있었습니다. 1024 바이트는 (플러시하지 않고) 쓸 것이고, 나이를 알아 내었지만, 결국에는 플러시하여 다른 324 바이트를 옮겼습니다. – Dave

11

"using"또는 streamWriter.Flush()를 사용하지 않으므로 작성자가 스트림에 변경 내용을 커밋하지 않았습니다. 결과 스트림 자체에는 아직 데이터가 없습니다. 일반적으로 Stream 및 StremaWriter 인스턴스를 사용하여 조작을 래핑합니다.

또한 MemoryStream을의 새로운 인스턴스를 반환 고려해야합니다

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

왜 MemoryStream의 새 인스턴스를 반환하겠습니까? 비효율적이고 중복되지 않습니까? – jsmith

+4

쓰기 전용 스트림에 할당 된 여분의 메모리를 사용하지 않으려면 스트림 작성시 "사용"하는 일반 스트림 코드 패턴을 허용하려면 읽기 전용으로 만드십시오. 이 특별한 경우에는별로 중요하지 않지만 호출자가 스트림을 닫거나 변경하는 경우 걱정없이 원하는대로 사용할 수있는 스트림을 반환하는 것이 좋습니다. 이 특별한 경우에는 ToArray (내부 버퍼의 복사본을 만듭니다) 대신 GetBuffer를 사용하여 매우 효율적으로 새 스트림을 만들 수 있습니다. –