InMemoryRandomAccessStream InMemoryRandomAccessStream InMemoryRandomAccessStream InMemoryRandomAccessStream Class

Definition

Provides random access of data in input and output streams that are stored in memory instead of on disk.

public : sealed class InMemoryRandomAccessStream : IClosable, IInputStream, IOutputStream, IRandomAccessStreampublic sealed class InMemoryRandomAccessStream : IDisposable, IInputStream, IOutputStream, IRandomAccessStreamPublic NotInheritable Class InMemoryRandomAccessStream Implements IDisposable, IInputStream, IOutputStream, IRandomAccessStream// You can use this class in JavaScript.
Attributes
Windows 10 requirements
Device family
Windows 10 (introduced v10.0.10240.0)
API contract
Windows.Foundation.UniversalApiContract (introduced v1)

Examples

The following example shows how to write and read strings to an in-memory stream. For the full code sample, see Reading and writing data sample.

#include "pch.h"
#include "WriteReadStream.xaml.h"

using namespace Concurrency;
using namespace DataReaderWriter;
using namespace Platform;
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Navigation;

Array<String^>^ _inputElements = ref new Array<String^>
{
    "Hello", "World", "1 2 3 4 5", "Très bien!", "Goodbye"
};

WriteReadStream::WriteReadStream()
{
    InitializeComponent();

    // Populate the text block with the input elements.
    ElementsToWrite->Text = "";
    for (unsigned int i = 0; i < _inputElements->Length; i++)
    {
        ElementsToWrite->Text += _inputElements[i] + ";";
    }
}

// Invoked when this page is about to be displayed in a Frame.
void WriteReadStream::OnNavigatedTo(NavigationEventArgs^ e)
{
    // Get a pointer to our main page.
    rootPage = MainPage::Current;
}

// This is the click handler for the 'Copy Strings' button.  Here we will parse the
// strings contained in the ElementsToWrite text block, write them to a stream using
// DataWriter, retrieve them using DataReader, and output the results in the
// ElementsRead text block.
void DataReaderWriter::WriteReadStream::TransferData(
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    // Initialize the in-memory stream where data will be stored.
    InMemoryRandomAccessStream^ stream = ref new InMemoryRandomAccessStream();

    // Create the DataWriter object backed by the in-memory stream. When
    // dataWriter is deleted, it will also close the underlying stream.
    DataWriter^ dataWriter = ref new DataWriter(stream->GetOutputStreamAt(0));
    dataWriter->UnicodeEncoding = UnicodeEncoding::Utf8;
    dataWriter->ByteOrder = ByteOrder::LittleEndian;

    // Create the data reader by using the input stream set at position 0 so that 
    // the stream will be read from the beginning regardless of where the position
    // the original stream ends up in after the store.
    IInputStream^ inputStream = stream->GetInputStreamAt(0);
    DataReader^ dataReader = ref new DataReader(inputStream);
    // The encoding and byte order need to match the settings of the writer 
    // we previously used.
    dataReader->UnicodeEncoding = UnicodeEncoding::Utf8;
    dataReader->ByteOrder = ByteOrder::LittleEndian;

    // Write the input data to the output stream.  Serialize the elements by writing
    // each string separately, preceded by its length.
    for (unsigned int i = 0; i < _inputElements->Length; i++) 
    {
        unsigned int inputElementSize = dataWriter->MeasureString(_inputElements[i]);
        dataWriter->WriteUInt32(inputElementSize);
        dataWriter->WriteString(_inputElements[i]);
    }

    // Send the contents of the writer to the backing stream.
    create_task(dataWriter->StoreAsync()).then([this, dataWriter] (unsigned int bytesStored)
    {
        // For the in-memory stream implementation we are using, the FlushAsync() call 
        // is superfluous, but other types of streams may require it.
        return dataWriter->FlushAsync();
    }).then([this, dataReader, stream] (bool flushOp)
    {
        // Once we have written the contents successfully we load the stream.
        return dataReader->LoadAsync((unsigned int) stream->Size);
    }).then([this, dataReader] (task<unsigned int> bytesLoaded)
    {
        try
        {
            // Check for possible exceptions that could have been thrown 
            // in the async call chain.
            bytesLoaded.get();

            String^ readFromStream = "";

            // Keep reading until we consume the complete stream.
            while (dataReader->UnconsumedBufferLength > 0)
            {
                // Note that the call to ReadString requires a length of 
                // "code units" to read. This is the reason each string is 
                // preceded by its length when "on the wire".
                unsigned int bytesToRead = dataReader->ReadUInt32();
                readFromStream += dataReader->ReadString(bytesToRead) + "\n";
            }

            // Populate the ElementsRead text block with the items we read from the stream
            ElementsRead->Text = readFromStream;
        }
        catch (Exception^ e)
        {
            ElementsRead->Text = "Error: " + e->Message;
        }
    });
}

using System;
using System.Diagnostics;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

// This is the click handler for the 'Copy Strings' button.  Here we will parse the
// strings contained in the ElementsToWrite text block, write them to a stream using
// DataWriter, retrieve them using DataReader, and output the results in the
// ElementsRead text block.
private async void TransferData(object sender, RoutedEventArgs e)
{
    // Initialize the in-memory stream where data will be stored.
    using (var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
    {
        // Create the data writer object backed by the in-memory stream.
        using (var dataWriter = new Windows.Storage.Streams.DataWriter(stream))
        {
            dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
            dataWriter.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;

            // Parse the input stream and write each element separately.
            string[] inputElements = ElementsToWrite.Text.Split(';');
            foreach (string inputElement in inputElements)
            {
                uint inputElementSize = dataWriter.MeasureString(inputElement);
                dataWriter.WriteUInt32(inputElementSize);
                dataWriter.WriteString(inputElement);
            }

            // Send the contents of the writer to the backing stream.
            await dataWriter.StoreAsync();

            // For the in-memory stream implementation we are using, the flushAsync call 
            // is superfluous,but other types of streams may require it.
            await dataWriter.FlushAsync();

            // In order to prolong the lifetime of the stream, detach it from the 
            // DataWriter so that it will not be closed when Dispose() is called on 
            // dataWriter. Were we to fail to detach the stream, the call to 
            // dataWriter.Dispose() would close the underlying stream, preventing 
            // its subsequent use by the DataReader below.
            dataWriter.DetachStream();
        }

        // Create the input stream at position 0 so that the stream can be read 
        // from the beginning.
        using (var inputStream = stream.GetInputStreamAt(0))
        {
            using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream))
            {
                // The encoding and byte order need to match the settings of the writer 
                // we previously used.
                dataReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                dataReader.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;

                // Once we have written the contents successfully we load the stream.
                await dataReader.LoadAsync((uint)stream.Size);

                var receivedStrings = "";

                // Keep reading until we consume the complete stream.
                while (dataReader.UnconsumedBufferLength > 0)
                {
                    // Note that the call to readString requires a length of "code units" 
                    // to read. This is the reason each string is preceded by its length 
                    // when "on the wire".
                    uint bytesToRead = dataReader.ReadUInt32();
                    receivedStrings += dataReader.ReadString(bytesToRead) + "\n";
                }

                // Populate the ElementsRead text block with the items we read 
                // from the stream.
                ElementsRead.Text = receivedStrings;
            }
        }
    }
}

(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/write-read-stream.html", {
        ready: function (element, options) {
            var sourceElement = document.getElementById("ElementsToSend");
            sourceElement.innerHTML = "Hello;World;1 2 3 4 5;Très bien!;Goodbye";
            var sendButton = document.getElementById("SendButton");
            sendButton.addEventListener("click", transferData);
        }
    });

function transferData() {
        var sourceElement = document.getElementById("ElementsToSend");
        var destinationElement = document.getElementById("scenario1Output");

        // First a DataWriter object is created, backed by an in-memory stream where 
        // the data will be stored.
        var writer = Windows.Storage.Streams.DataWriter(
            new Windows.Storage.Streams.InMemoryRandomAccessStream());
        writer.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf8;
        writer.byteOrder = Windows.Storage.Streams.ByteOrder.littleEndian;

        // We separate the contents of the sourceElement div in multiple strings 
        // using ';' as the separator. Each string will be written separately.
        var elements = sourceElement.innerHTML.split(";");
        elements.forEach(function (element) {
            var codeUnits = writer.measureString(element);
            writer.writeInt32(codeUnits);
            writer.writeString(element);
        });

        var reader;
        var stream;

        // The call to store async sends the actual contents of the writer 
        // to the backing stream.
        writer.storeAsync().then(function () {
            // For the in-memory stream implementation we are using, the flushAsync call 
            // is superfluous, but other types of streams may require it.
            return writer.flushAsync();
        }).then(function () {
            // We detach the stream to prolong its useful lifetime. Were we to fail 
            // to detach the stream, the call to writer.close() would close the underlying 
            // stream, preventing its subsequent use by the DataReader below. Most clients 
            // of DataWriter will have no reason to use the underlying stream after 
            // writer.close() is called, and will therefore have no reason to call
            // writer.detachStream(). Note that once we detach the stream, we assume 
            // responsibility for closing the stream subsequently; after the stream 
            // has been detached, a call to writer.close() will have no effect on the stream.
            stream = writer.detachStream();
            // Make sure the stream is read from the beginning in the reader 
            // we are creating below.
            stream.seek(0);
            // Most DataWriter clients will not call writer.detachStream(), 
            // and furthermore will be working with a file-backed or network-backed stream, 
            // rather than an in-memory-stream. In such cases, it would be particularly 
            // important to call writer.close(). Doing so is always a best practice.
            writer.close();

            reader = new Windows.Storage.Streams.DataReader(stream);
            // The encoding and byte order need to match the settings of the writer 
            // we previously used.
            reader.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf8;
            reader.byteOrder = Windows.Storage.Streams.ByteOrder.littleEndian;
            // Once we have written the contents successfully we load the stream, 
            // this is also an asynchronous operation
            return reader.loadAsync(stream.size);
        }).done(function () {
            var receivedStrings = "";
            // Keep reading until we consume the complete stream
            while (reader.unconsumedBufferLength > 0) {
                // Note that the call to readString requires a length of "code units" 
                // to read. This is the reason each string is preceeded by its length 
                // when "on the wire".
                var codeUnitsToRead = reader.readInt32();
                receivedStrings += reader.readString(codeUnitsToRead) + "<br/>";
            }
            // Calling reader.close() closes the underlying stream. It would be particularly important
            // to call reader.close() if the underlying stream were file-backed or 
            // network-backed. Note that this call to reader.close() satisfies 
            // our obligation to close the stream previously detached from DataReader.
            reader.close();
            destinationElement.innerHTML = receivedStrings;
        });
    };
})();

Constructors

InMemoryRandomAccessStream() InMemoryRandomAccessStream() InMemoryRandomAccessStream() InMemoryRandomAccessStream()

Creates a new instance of the InMemoryRandomAccessStream class.

public : InMemoryRandomAccessStream()public InMemoryRandomAccessStream()Public Sub New()// You can use this method in JavaScript.

Properties

CanRead CanRead CanRead CanRead

Gets a value that indicates whether the stream can be read from.

public : PlatForm::Boolean CanRead { get; }public bool CanRead { get; }Public ReadOnly Property CanRead As bool// You can use this property in JavaScript.
Value
PlatForm::Boolean bool bool bool

True if the stream can be read from. Otherwise, false.

CanWrite CanWrite CanWrite CanWrite

Gets a value that indicates whether the stream can be written to.

public : PlatForm::Boolean CanWrite { get; }public bool CanWrite { get; }Public ReadOnly Property CanWrite As bool// You can use this property in JavaScript.
Value
PlatForm::Boolean bool bool bool

True if the stream can be written to. Otherwise, false.

Position Position Position Position

Gets the byte offset of the stream.

public : ulong Position { get; }public ulong Position { get; }Public ReadOnly Property Position As ulong// You can use this property in JavaScript.
Value
ulong ulong ulong ulong

The number of bytes from the start of the stream.

Size Size Size Size

Gets or sets the size of the random access stream.

public : ulong Size { get; set; }public ulong Size { get; set; }Public ReadWrite Property Size As ulong// You can use this property in JavaScript.
Value
ulong ulong ulong ulong

The size of the stream.

Methods

CloneStream() CloneStream() CloneStream() CloneStream()

Creates a new instance of a IRandomAccessStream over the same resource as the current stream.

public : IRandomAccessStream CloneStream()public IRandomAccessStream CloneStream()Public Function CloneStream() As IRandomAccessStream// You can use this method in JavaScript.
Returns

The new stream. The initial, internal position of the stream is 0.

The internal position and lifetime of this new stream are independent from the position and lifetime of the cloned stream.

Close() Close() Close() Close()

Closes the current stream and releases system resources.

public : void Close()This member is not implemented in C#This member is not implemented in VB.Net// You can use this method in JavaScript.

Dispose() Dispose() Dispose() Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

This member is not implemented in C++void Dispose()Sub Disposevoid Dispose()

FlushAsync() FlushAsync() FlushAsync() FlushAsync()

Flushes data asynchronously in a sequential stream.

public : IAsyncOperation<PlatForm::Boolean> FlushAsync()public IAsyncOperation<bool> FlushAsync()Public Function FlushAsync() As IAsyncOperation( Of bool )// You can use this method in JavaScript.
Returns

The stream flush operation.

Remarks

The FlushAsync method may produce latencies and does not always guarantee durable and coherent storage of data. It's generally recommended to avoid this method if possible.

GetInputStreamAt(UInt64) GetInputStreamAt(UInt64) GetInputStreamAt(UInt64) GetInputStreamAt(UInt64)

Returns an input stream at a specified location in a stream.

public : IInputStream GetInputStreamAt(unsigned __int64 position)public IInputStream GetInputStreamAt(UInt64 position)Public Function GetInputStreamAt(position As UInt64) As IInputStream// You can use this method in JavaScript.
Parameters
position
unsigned __int64 UInt64 UInt64 UInt64

The location in the stream at which to begin.

Returns

GetOutputStreamAt(UInt64) GetOutputStreamAt(UInt64) GetOutputStreamAt(UInt64) GetOutputStreamAt(UInt64)

Returns an output stream at a specified location in a stream.

public : IOutputStream GetOutputStreamAt(unsigned __int64 position)public IOutputStream GetOutputStreamAt(UInt64 position)Public Function GetOutputStreamAt(position As UInt64) As IOutputStream// You can use this method in JavaScript.
Parameters
position
unsigned __int64 UInt64 UInt64 UInt64

The location in the output stream at which to begin.

Returns

ReadAsync(IBuffer, UInt32, InputStreamOptions) ReadAsync(IBuffer, UInt32, InputStreamOptions) ReadAsync(IBuffer, UInt32, InputStreamOptions) ReadAsync(IBuffer, UInt32, InputStreamOptions)

Returns an asynchronous byte reader object.

public : IAsyncOperationWithProgress<IBuffer, unsigned int> ReadAsync(IBuffer buffer, unsigned int count, InputStreamOptions options)public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, UInt32 count, InputStreamOptions options)Public Function ReadAsync(buffer As IBuffer, count As UInt32, options As InputStreamOptions) As IAsyncOperationWithProgress( Of IBuffer, uint )// You can use this method in JavaScript.
Parameters
buffer
IBuffer IBuffer IBuffer IBuffer

The buffer into which the asynchronous read operation places the bytes that are read.

count
unsigned int UInt32 UInt32 UInt32

The number of bytes to read that is less than or equal to the Capacity value.

options
InputStreamOptions InputStreamOptions InputStreamOptions InputStreamOptions

Specifies the type of the asynchronous read operation.

Returns

Seek(UInt64) Seek(UInt64) Seek(UInt64) Seek(UInt64)

Sets the position of the stream to the specified value.

public : void Seek(unsigned __int64 position)public void Seek(UInt64 position)Public Function Seek(position As UInt64) As void// You can use this method in JavaScript.
Parameters
position
unsigned __int64 UInt64 UInt64 UInt64

The new position of the stream.

Remarks

Warning

This method does not check the position to make sure the value is valid for the stream. If the position is invalid for the stream, the ReadAsync and WriteAsync methods will return an error if you call them.

WriteAsync(IBuffer) WriteAsync(IBuffer) WriteAsync(IBuffer) WriteAsync(IBuffer)

Writes data asynchronously in a sequential stream.

public : IAsyncOperationWithProgress<unsigned int, unsigned int> WriteAsync(IBuffer buffer)public IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)Public Function WriteAsync(buffer As IBuffer) As IAsyncOperationWithProgress( Of uint, uint )// You can use this method in JavaScript.
Parameters
buffer
IBuffer IBuffer IBuffer IBuffer

The buffer into which the asynchronous writer operation writes.

Returns

The byte writer operation.