I'm trying to get an IRandomAccessStream for a specified byte range in a StorageFile, using C++/WinRT in a UWP app. This is in order to respond to partial GET requests with WebView2: CreateWebResourceResponse() takes an IRandomAccessStream for the response data. Note I can't use SetVirtualHostNameToFolderMapping, because it doesn't handle partial GETs - the very problem I am trying to solve.
StorageFile.OpenReadAsync() gives a random access stream to the entire file contents. However seeking it does not seem to have any effect - it seems CreateWebResourceResponse() reads the stream from the very beginning ignoring the current seek position. So it seems I need an IRandomAccessStream which represents the byte range of the file where position 0 is the beginning of the range and the size of the stream is the size of the range.
In another Win32 app I memory map the file and create a stream on the relevant byte range, but it doesn't seem to be possible to memory map files in UWP apps.
The best I've come up with is using DataReader and DataWriter to read the relevant range of the file, and write it to a new stream, like this:
Streams::IRandomAccessStream fileStream = co_await storageFile.OpenReadAsync();
Streams::DataReader dataReader{ fileStream.GetInputStreamAt(rangeStartPos) };
Streams::InMemoryRandomAccessStream responseStream;
Streams::DataWriter dataWriter{ responseStream };
co_await dataReader.LoadAsync(static_cast<uint32_t>(rangeLength));
Streams::IBuffer buffer = dataReader.ReadBuffer(static_cast<uint32_t>(rangeLength));
dataWriter.WriteBuffer(buffer);
Unfortunately this has poor performance - sometimes a range request will be made for a range like 1mb-200mb of a video file, and this means reading and copying hundreds of megabytes of data in memory, and it's not really streaming, as it's just reading the entirety of the given range and then dumping it in to another stream.
So how can a truly streaming IRandomAccessStream be created for a given byte range of a StorageFile? Do I have to write a custom stream class for this case, and if so, how would I do that?