[C#] 스트림 리더를 폐기하면 스트림이 닫히나요?

쓰려는 메소드에 스트림을 보내고 있으며,이 메소드에서는 이진 리더 / wrtier를 사용하고 있습니다. 리더 / 라이터가 처리 using되지 않거나 참조되지 않은 경우 스트림도 닫힙니 까?

BinaryReader / Writer를 보내려고하지만 StreamReader도 사용하고 있습니다. 라이터 / 리더가 닫힐 때마다 스트림을 닫으면 상당히 번거 롭습니다.



답변

예, StreamReader, StreamWriter, BinaryReader그리고 BinaryWriter당신이 호출 할 때 모든 가까운 / 자신의 기본 스트림을 처리 Dispose그들. 그들은 하지 않는 리더 / 라이터가 단지 쓰레기 불구 수집하는 경우 스트림 처분 – 당신이해야 항상 처분 리더 / 라이터의, 양호하게는 A의 using문. (실제로이 클래스 중 어느 것도 마무리 요소를 갖지 않아야합니다.)

개인적으로 나는 스트림에 대한 using 문을 선호합니다. using중괄호없이 명령문을 깔끔하게 중첩 할 수 있습니다 .

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

using스트림에 대한 문장이 약간 중복되어 있지만 ( StreamReader생성자가 예외를 throw 하지 않는 한 ) 나는 그것을 제거 StreamReader하고 나중에 스트림을 직접 사용하는 것이 가장 좋은 방법이라고 생각합니다. 의미론.


답변

이것은 오래된 것이지만 오늘 비슷한 일을하고 싶었고 일이 바뀌 었다는 것을 알았습니다. .net 4.5부터는 leaveOpen인수가 있습니다.

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

유일한 문제는 다른 매개 변수에 대해 무엇을 설정해야하는지 명확하지 않다는 것입니다. 도움이 필요합니다 :

에서 은 MSDN 페이지 에서는 StreamReader 생성자 (스트림)에 대한 :

이 생성자는 UTF8Encoding, stream 매개 변수를 사용하는 BaseStream 속성 및 내부 버퍼 크기를 1024 바이트로 인코딩을 초기화합니다.

그건 단지 잎 detectEncodingFromByteOrderMarks으로 판단 소스 코드 입니다true

public StreamReader(Stream stream)
        : this(stream, true) {
}

public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
        : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}

이러한 기본값 중 일부가 노출되었거나 인수가 선택적인 경우 원하는 값을 지정할 수 있으면 좋을 것입니다.


답변

그렇습니다. Reflector를 사용한 구현을 보면이를 확인할 수 있습니다.

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {
            this.stream = null;
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}


답변

6 년 늦었지만 어쩌면 이것은 누군가를 도울 수 있습니다.

StreamReader는 연결이 끊어 질 때 연결을 닫습니다. 그러나 “StreamStream = …) {…}”을 StreamReader / StreamWriter와 함께 사용하면 Stream이 두 번 처리 될 수 있습니다. 닫힙니다. VS의 코드 분석을 실행할 때 CA2202 경고가 발생합니다.

CA2202 에서 직접 가져온 다른 솔루션 페이지 은 try / finally 블록을 사용하는 것입니다. 올바르게 설정하면 연결이 한 번만 닫힙니다.

CA2202 하단 근처에서 다음을 사용하는 것이 좋습니다.

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

대신에…

// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
    // Use the reader object...
}


답변

예. Dispose ()를 호출하고 IDisposable을 “사용”하면 개체가 모든 리소스를 정리해야합니다. 여기에는 파일 디스크립터를 비우고 닫는 스트림이 포함됩니다.

귀하의 경우 다른 방법으로 전달하려면 해당 방법이 using 블록에서 읽기 / 쓰기를 수행하지 않아야합니다.


답변

필요한 경우이 문제를 해결하는 쉬운 방법은 StreamWriter 클래스 Dispose 메서드를 재정의하는 것입니다. 방법에 대한 코드는 여기 내 게시물을 참조하십시오.

StreamWriter를 폐기하면 기본 스트림이 닫히나요?


답변

키워드를 “사용”하거나 dispose를 명시 적으로 호출하여 처리 된 스트림