[c#] BaseStream을 닫지 않고 StreamWriter를 닫는 방법이 있습니까?

내 루트 문제 즉 using통화DisposeStreamWriter, 그것은 또한 처분 BaseStream(같은 문제로를 Close).

이에 대한 해결 방법이 있지만 보시다시피 스트림 복사가 포함됩니다. 스트림을 복사하지 않고이 작업을 수행 할 수있는 방법이 있습니까?

이것의 목적은 문자열의 내용 (원래 데이터베이스에서 읽음)을 스트림으로 가져 와서 제 3 자 구성 요소에서 스트림을 읽을 수 있도록하는 것입니다.
NB : 타사 구성 요소를 변경할 수 없습니다.

public System.IO.Stream CreateStream(string value)
{
    var baseStream = new System.IO.MemoryStream();
    var baseCopy = new System.IO.MemoryStream();
    using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
    {
        writer.Write(value);
        writer.Flush();
        baseStream.WriteTo(baseCopy);
    }
    baseCopy.Seek(0, System.IO.SeekOrigin.Begin);
    return baseCopy;
}

사용

public void Noddy()
{
    System.IO.Stream myStream = CreateStream("The contents of this string are unimportant");
    My3rdPartyComponent.ReadFromStream(myStream);
}

이상적으로 불리는 가상의 방법을 찾고 있어요 BreakAssociationWithBaseStream, 예를 들어,

public System.IO.Stream CreateStream_Alternate(string value)
{
    var baseStream = new System.IO.MemoryStream();
    using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
    {
        writer.Write(value);
        writer.Flush();
        writer.BreakAssociationWithBaseStream();
    }
    return baseStream;
}



답변

.NET Framework 4.5 이상을 사용하는 경우 작성기가 닫힐 때 기본 스트림을 열어 두도록 요청할 수 있는 StreamWriter 오버로드가 있습니다 .

4.5 이전 버전의 .NET Framework StreamWriter 에서는 스트림을 소유 한다고 가정 합니다. 옵션 :

  • 처분하지 마십시오 StreamWriter; 그냥 플러시하십시오.
  • Close/에 대한 호출을 무시 Dispose하지만 다른 모든 것을 프록시 하는 스트림 래퍼를 만듭니다 . 거기에서 가져오고 싶다면 MiscUtil 에서 구현 했습니다.

답변

.NET 4.5에는 새로운 방법이 있습니다!

http://msdn.microsoft.com/EN-US/library/gg712853(v=VS.110,d=hv.2).aspx

public StreamWriter(
    Stream stream,
    Encoding encoding,
    int bufferSize,
    bool leaveOpen
)


답변

간단하게 호출하지 않습니다 DisposeStreamWriter. 이 클래스가 삭제되는 이유는 관리되지 않는 리소스를 보유하기 때문이 아니라 자체적으로 관리되지 않는 리소스를 보유 할 수있는 스트림의 처리를 허용하기 때문입니다. 기본 스트림의 수명이 다른 곳에서 처리되는 경우 작성자를 삭제할 필요가 없습니다.


답변

메모리 스트림에는 스트림이 닫혀 있어도 사용할 수있는 ToArray 속성이 있습니다. To Array는 Position 속성에 관계없이 스트림 내용을 바이트 배열에 씁니다. 작성한 스트림을 기반으로 새 스트림을 만들 수 있습니다.

public System.IO.Stream CreateStream(string value)
{
    var baseStream = new System.IO.MemoryStream();
    var baseCopy = new System.IO.MemoryStream();
    using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
    {
        writer.Write(value);
        writer.Flush();
        baseStream.WriteTo(baseCopy);
    }
    var returnStream = new System.IO.MemoryStream( baseCopy.ToArray());
    return returnStream;
}


답변

StreamWriter의 하위 항목을 만들고 dispose 메서드를 재정의해야합니다. 항상 disposing 매개 변수에 false를 전달하면 스트림 작성기가 닫히지 않습니다. StreamWriter는 close 메서드에서 dispose를 호출하기 만하면됩니다. 재정의하십시오 (물론 원하는 경우 모든 생성자를 추가 할 수 있습니다.

public class NoCloseStreamWriter : StreamWriter
{
    public NoCloseStreamWriter(Stream stream, Encoding encoding)
        : base(stream, encoding)
    {
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(false);
    }
}


답변