MemoryMappedFile 관련 Span<T>

.NET은 MemoryMappedFile을 이용해 메모리 매핑 파일을 이용할 수 있습니다. 다만, C언어에서 매핑된 주소를 메모리 주소처럼 접근할 수 있는데 반해 C#은 메모리를 직접 다루는 언어가 아니니만큼 두가지 방식을 통해 접근을 할 수 있게 합니다.

  1. MemoryMappedViewAccessor
    CreateViewAccessor()메소드를 이용해 메모리 매핑 파일에 접근할 수 있게 합니다. 인자를 주지 않으면 메모리 매핑 파일 전체를 접근할 수 있으며, positionlength로 부분 접근 Accessor를 생성할 수도 있습니다… 이후, Accessor를 통해 position위치의 값을 읽거나 쓸 수 있게 됩니다.
    관리메모리를 사용하는 C# 언어에서는 이런식의 방법이 최선일수밖에 없지만, 아쉽군요. 파일영역을 OS의 힘을 빌려 메모리처럼 접근할 수만 있다면 대량 데이터를 처리하는데 이점이 있을텐데요.

  2. MemoryMappedViewStream 클래스 (System.IO.MemoryMappedFiles) | Microsoft Docs
    다른 방식으로는 CreateViewStream()을 통해 스트림으로 접근하는 방식입니다. 사용법은 기본Stream과 동일합니다.

Span를 통해 MemoryMappedFile을 사용할 수 있겠다 싶어서 접근을 했던것인데요. 아직은 Accessor의 지원이 없습니다. 해서 관련 github의 활동을 검색해봤는데 그럴만한 이유는 있더군요.

API Proposal: Add Span accessor for MemoryMapped files · Issue #37227 · dotnet/runtime (github.com)
아직 Span<T>형태를 안정적으로 제공할 만한 형태를 찾지 못한듯 합니다. (access violation 등)

그래도 방법이 없을수야 없겠지요. 어쨌든 MemoryMappedFiles도 내부적으로는 운영체제의 API를 이용해야만 합니다.

How memory mapping files are accessed as a variable?If not, is it possible? · Issue #42736 · dotnet/runtime (github.com)
이 글에서는 핸들을 통해 포인터를 획득하는 가이드가 나옵니다.

코드로 아직 테스트를 해보지는 않았지만, 글로만 봤을 때는 저 포인터를 Span<byte> 또는 Memory<byte>으로 변환하여 사용하면 되지 않을까 생각해봅니다.

1개의 좋아요

MemoryMappedFile 은 단순히 파일 엑세스 뿐만 아니라 한 시스템에서 다른 여러 프로세스에서 데이터를 공유 할 수 있다는 것이 가장 큰 장점 같습니다.

2개의 좋아요