2010-01-05 4 views
1

보내진 POST 데이터를 처리하는 C#으로 작성된 TCP 서버가 있습니다. 현재 많은 양의 데이터 (1GB 이상)가 전송되지 않으면 메모리가 부족합니다 (목록 DTO를 매개로 바이트 배열로 메모리에 저장). 대용량 파일의 경우 이제 디스크로 스트리밍 한 다음 디스크에서 스트리밍하려는 의도로 파일 이름을 전달합니다.TCP 서버 및 MemoryStreams/ByteArrays

현재 모든 루틴은 바이트 배열이 예상되며, 궁금한 점이 있다면 약간 근시안적입니다. Bytearray를 memorystream로 변환하면 메모리 사용량이 두 배가됩니까? Memorystream에서 작동하도록 코드를 다시 작성하면 디스크에서 스트림을 읽을 때 다시 사용할 수 있습니다.

어리석은 질문에 대해 미안하지만, C#이 데이터 사본을 가져 오거나 참조를받을 때 확신 할 수 없습니다.

답변

1

MemoryStream으로 전달하면 데이터는 처음에는 생성자에서 복사되지만 byte[]을 릴리스하면 가비지 수집 될 수 있습니다. 본질적으로 "이중화"가 없습니다 (특히 크기를 정확하게 설정하여 byte[]이 아닌 Stream에 직접 쓸 수있는 경우).

나는 완전히 말을 스위치에 Stream (API를뿐만 사용 Stream - 아무것도 moer의 특정, 당신이 소요되는 코드 유형을 알 필요가 없습니다). 가장 중요한 점은 NetworkStream (소켓에서 직접 읽음) 또는 FileStream (디스크에 버퍼하려는 경우)을 사용하도록 선택하거나 처리 중에 버퍼링하려는 경우 MemoryStream을 사용할 수 있습니다. 또한 스트림 기반 코드를 통해 해당 볼륨의 데이터를 읽어야합니다. 반복자 블록 (yield return)은 LINQ Enumerable 메서드 (마찬가지로 OrderBy, GroupBy 등 제외)와 마찬가지로 매우 유용합니다.

byte[]을 전달하거나 Stream을 전달하지 않으면 참조 유형이므로 참조가 복사됩니다 (x86/x64에 따라 4 또는 8 바이트).

0

MemoryStream은 바이트 배열 주위의 스트림 래퍼이므로, 사용하면 아무 것도 얻을 수 없습니다.

최소한 (대용량 파일의 경우) 수행해야 할 것은 FileStream을 열고 거기에 데이터를 덤프합니다. 하위 레벨에서는 연결에서 X 바이트를 읽은 다음 즉시 파일 스트림에 써야합니다. 이렇게하면 전체 공연을 메모리에 넣지 않고 한 번에 몇 바이트 만 가져옵니다.

쉽게 처리 할 수 ​​있는지 여부는 TCP 서버가 코딩 된 방법에 따라 다릅니다.

0

바이트가 값 유형이기 때문에 ref 키워드없이 함수에 전달하면 매번 복사본을 처리하게됩니다. ref 키워드와 함께 전달하면 원래 바이트 배열을 참조하게됩니다.

memorystream은 참조 유형이므로 데이터를 복사하지 않지만 해당 데이터에 대한 참조를 전달하므로 메모리 사용량이 두 배로 늘어나지 않습니다.

+0

OP는 바이트 []를 전달하는 것에 대해 질문하고 있으며 모든 배열이 참조 유형임을 알고 있습니다. 값 유형 (이 경우에는 바이트)을 보유 할 수 있지만 배열 자체는 참조 유형입니다. – trickdev