2012-01-22 5 views

답변

9

시나리오를 사용하면 원래 스트림을 바꿀 수있는 경우 해당 스트림이 검색을 지원하는지 여부를 확인할 수 있으며 내용을 읽은 후 새로운 MemoryStream으로 다시 감쌀 수 있습니다. 그런 다음 후속 작업에 사용할 수 있습니다.

static string PeekStream(ref Stream stream) 
{ 
    string content; 
    var reader = new StreamReader(stream); 
    content = reader.ReadToEnd(); 

    if (stream.CanSeek) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
    } 
    else 
    { 
     stream.Dispose(); 
     stream = new MemoryStream(Encoding.UTF8.GetBytes(content)); 
    } 

    return content; 
} 

위의 내용은 콘텐츠 크기의 두 배에 해당하는 메모리를 할당해야하므로 비효율적입니다. 내 권장 사항은 대신 콘텐츠의 저장된 사본에 액세스 할 수 있도록 (모든 콘텐츠를 읽은 후) 스트림에 액세스하는 코드의 일부를 수정하는 것입니다. 예를 들면 다음과 같습니다 StringReader 그냥 content 문자열에서 읽어

string content; 
using (var reader = new StreamReader(stream)) 
    content = reader.ReadToEnd(); 

// Process content here. 

string line; 
using (var reader = new StringReader(content)) 
    while ((line = reader.ReadLine()) != null) 
     Console.WriteLine(line); 

때문에, 당신은 데이터의 중복 복사본을 생성 메모리를 낭비하지 않을 것입니다.

+0

이 방법은 매우 큰 데이터가있을 때까지 정확합니다. 몇 기가 바이트가 있으면 스트림을 다시 초기화하는 것이 좋습니다. 제 생각에는 스트리밍의 목적은 처리중인 모든 데이터를 저장하지 않는 것입니다. –

+0

대용량 데이터에는 부적합한'MemoryStream'에 대해 옳습니다. 스트림을 저장할지 또는 다시 초기화할지 여부는 시나리오에 따라 다릅니다. 예를 들어, 인터넷에서 다운로드 한 데이터를 처리하고 여러 번 읽어야하는 경우 데이터를 다시 다운로드하는 것보다 로컬로 (메모리 또는 임시 파일에) 저장하는 것이 좋습니다. – Douglas

5

검색을 지원하는 다른 스트림 구현을 사용하십시오. Stream.CanSeek이 false를 반환하면 해당 구현은 검색을 지원하지 않는다고 주장합니다.

MemoryStream 개체는 검색을 지원합니다. 임의의 스트림을 이와 같이 사용하여 MemoryStream에 복사 할 수 있으며 결과 스트림은 검색을 지원합니다. 예를 들어 위치를 0으로 재설정하고 반복적으로 읽을 수 있습니다. 스트림이 변경되지 않는 데이터를 읽는 경우

MemoryStream CopyStreamToMemory(Stream inputStream) 
{ 
    MemoryStream ret = new MemoryStream(); 
    const int BUFFER_SIZE = 1024; 
    byte[] buf = new byte[BUFFER_SIZE]; 

    int bytesread = 0; 
    while ((bytesread = inputStream.Read(buf, 0, BUFFER_SIZE)) > 0) 
     ret.Write(buf, 0, bytesread); 

    ret.Position = 0; 
    return ret; 
} 

은 물론, 당신은 단순히 이전 스트림을 처리하고, 동일한 데이터를 읽는 새로운 스트림을 생성 할 수 있습니다.

관련 문제