Stream
매개 변수를 허용하는 유틸리티 메소드에서 나는 데이터를 분석하기 위해 StreamReader
에 의존합니다.범위에서 정의 된 스트림을 읽는 StreamReader를 삭제 하시겠습니까?
내 방법으로 들어오는 스트림을 닫고 싶지 않습니다. 나는 호출자 메소드가 스트림을 처리하기로 결정할 수 있도록하고 싶다.
열린 상태로 처분하지 않는 것이 안전합니까? StreamReader
? 내 말은 결국 자동적으로 처분 될 것인가? 메모리 누수가 발생합니까?
여기 내 유틸리티 방법입니다. 그것의 목표는 관계없이 데이터를 인코딩하는 방법, 스트림을 읽고 문자열로 내용을 반환하는 것입니다 :
public static string GetStringAutoDetectEncoding(Stream data, out Encoding actualEncoding)
{
// 1. Is there a Bye Order Mask ?
var candidateEncoding = DetectEncodingWithByteOrderMask(data);
// 2a. No BOM, the data is either UTF8 no BOM or ANSI
if (candidateEncoding == Encoding.Default)
{
var utf8NoBomEncoding = Encoding.GetEncoding("utf-8",new EncoderExceptionFallback(), new DecoderExceptionFallback());
var positionBackup = data.Position;
var sr = new StreamReader(data, utf8NoBomEncoding);
try
{
// 3. Try as UTF8 With no BOM
var result = sr.ReadToEnd(); // will throw error if not UTF8
actualEncoding = utf8NoBomEncoding; // Probably an UTF8 no bom string
return result;
}
catch (DecoderFallbackException)
{
// 4. Rewind the stream and fallback to ASNI
data.Position = positionBackup;
var srFallback = new StreamReader(data, candidateEncoding);
actualEncoding = candidateEncoding;
return srFallback.ReadToEnd(); ;
}
}
// 2b. There is a BOM. Use the detected encoding
else
{
var sr = new StreamReader(data, candidateEncoding);
actualEncoding = candidateEncoding;
return sr.ReadToEnd(); ;
}
}
그럼,이 같은 몇 가지 방법이 있습니다 :
void Foo(){
using(var stream = File.OpenRead(@"c:\somefile")) {
Encoding detected;
var fileContent = MyUtilityClass.GetStringAutoDetectEncoding(stream, detected);
Console.WriteLine("Detected encoding: {0}", encoding);
Console.WriteLine("File content: {0}", fileContent);
}
}
사실 내 유틸리티 메소드는 일반적인 용도의 라이브러리이지만 스트림을 여는 것은 내 프로그램에 있습니다. StreamReader의 논리가 프로그램으로 옮겨지면 코드 스 니펫을 이해할 수 없습니다. –
동기 부여는 기본적으로 스트림을 열고 닫는 실제 작업을 처리하는 별도의 메서드를 갖는 것이지만 실제 작업은 스트림이 열려있는 동안 수행해야하는 작업은 별도로 정의되고 전달됩니다. 이렇게하면 스트림이 다른 메소드로 '누출'하지 않아도됩니다. GC가 주변에 올 때마다 스트림을 닫는 것이 좋지 않은 것처럼 보입니다. 그리고 물론'StreamReader'도'StreamWork' 함수에 재 배열 할 수 있습니다. 핵심은 메서드에서 스트림을 누출하지 않는다는 것입니다. – sircodesalot
질문을 다시 읽었을 때 책임을 뒤집을 수 있다고 생각합니다. (내 업데이트 질문 참조). 사실, 내가 당신의 지시에 따라 간다면, 나는 (프로그램에서) 다음과 같이 끝날 것이다 :'var withOpenedStream = new Action> (a => {using (var stream = File.OpenRead (@ "c : \ temp.txt ")) {a (stream);}); MyUtility.GetStringAutoDetectEncoding (withOpenedStream, stream); 그리고 메서드 자체 : void GetStringAutoDetectEncoding (액션 <액션 > a, 스트림 s) {var 프로세스 = 새 액션 ((스트림) =>/* 스트림을 처리합니다. a (과정); }'. 꽤 못생긴 –