How to: Convert Between .NET Framework Streams and Windows Runtime Streams

The .NET Framework for Windows Store apps is a subset of the full .NET Framework. Because of security and other requirements for Windows Store apps, you cannot use the full set of .NET Framework APIs to open and read files. For more information, see .NET for Windows Store apps overview. However, you may want to use .NET Framework APIs for other stream manipulation operations. To manipulate these streams, you may find it necessary to convert between a .NET Framework stream type such as MemoryStream or FileStream, and a Windows Runtime stream such as IInputStream, IOutputStream, or IRandomAccessStream.

The System.IO.WindowsRuntimeStreamExtensions class contains methods that make these conversions easy. However, there are underlying differences between streams in the .NET Framework and the Windows Runtime that will affect the results of using these methods. The details are described in the following sections.

Converting from a Windows Runtime stream to a .NET Framework stream

You can convert from a Windows Runtime stream to a .NET Framework stream by using one of the following System.IO.WindowsRuntimeStreamExtensions methods:

`System.IO.WindowsRuntimeStreamExtensions.AsStream`

Converts a random-access stream in the Windows Runtime to a managed stream in the .NET for Windows Store apps subset.

`System.IO.WindowsRuntimeStreamExtensions.AsStreamForWrite`

Converts an output stream in the Windows Runtime to a managed stream in the .NET for Windows Store apps subset.

`System.IO.WindowsRuntimeStreamExtensions.AsStreamForRead`

Converts an input stream in the Windows Runtime to a managed stream in the .NET for Windows Store apps subset.

The Windows Runtime offers stream types that support reading only, writing only or reading and writing, and these capabilities are maintained when you convert a Windows Runtime stream to a .NET Framework stream. Furthermore, if you convert a Windows Runtime stream to a .NET Framework stream and back, you get the original Windows Runtime instance back. It’s best practice to use the conversion method that matches the capabilities of the Windows Runtime stream you would like to convert. However, since IRandomAccessStream is readable and writeable (it implements both IOutputStream and IInputStream), you can use any of the conversion methods and the capabilities of the original stream are maintained. For example, using System.IO.WindowsRuntimeStreamExtensions.AsStreamForRead to convert an IRandomAccessStream will not limit the converted .NET Framework stream to being readable only; it will also be writable.

To convert from a Windows Runtime random-access stream to a .NET Framework stream

  • Use the System.IO.WindowsRuntimeStreamExtensions.AsStream method.

    The following code example shows how to prompt the user to select a file, open it with Windows Runtime APIs, and then convert it to a .NET Framework stream, which is read and output to a text block. In this scenario, you would typically manipulate the stream with .NET Framework APIs before outputting the results.

    To run this example, you must create a Windows Store XAML app that contains a text block named TextBlock1 and a button named Button1. The button click event must be associated with the button1_Click method shown in the example.

    using System;
    using System.IO;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media.Imaging;
    using Windows.Storage;
    using System.Net.Http;
    using Windows.Storage.Pickers;
    
    Imports System.IO
    Imports System.Runtime.InteropServices.WindowsRuntime
    Imports Windows.UI.Xaml
    Imports Windows.UI.Xaml.Controls
    Imports Windows.UI.Xaml.Media.Imaging
    Imports Windows.Storage
    Imports System.Net.Http
    Imports Windows.Storage.Pickers
    
    private async void button1_Click(object sender, RoutedEventArgs e)
    {
        // Create a file picker.
        FileOpenPicker picker = new FileOpenPicker();
    
        // Set properties on the file picker such as start location and the type
        // of files to display.
        picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        picker.ViewMode = PickerViewMode.List;
        picker.FileTypeFilter.Add(".txt");
    
        // Show picker enabling user to pick one file.
        StorageFile result = await picker.PickSingleFileAsync();
    
        if (result != null)
        {
            try
            {
                // Retrieve the stream. This method returns a IRandomAccessStreamWithContentType.
                var stream = await result.OpenReadAsync();
    
                // Convert the stream to a .NET stream using AsStream, pass to a 
                // StreamReader and read the stream.
                using (StreamReader sr = new StreamReader(stream.AsStream()))
                {
                    TextBlock1.Text = sr.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                TextBlock1.Text = "Error occurred reading the file. " + ex.Message;
            }
        }
        else
        {
            TextBlock1.Text = "User did not pick a file";
        }
    }
    
    Private Async Sub button1_Click(sender As Object, e As RoutedEventArgs)
        ' Create a file picker.
        Dim picker As New FileOpenPicker()
    
        ' Set properties on the file picker such as start location and the type of files to display.
        picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary
        picker.ViewMode = PickerViewMode.List
        picker.FileTypeFilter.Add(".txt")
    
        ' Show picker that enable user to pick one file.
        Dim result As StorageFile = Await picker.PickSingleFileAsync()
    
        If result IsNot Nothing Then
            Try
                ' Retrieve the stream. This method returns a IRandomAccessStreamWithContentType.
                Dim stream = Await result.OpenReadAsync()
    
                ' Convert the stream to a .NET stream using AsStreamForRead, pass to a 
                ' StreamReader and read the stream.
                Using sr As New StreamReader(stream.AsStream())
                    TextBlock1.Text = sr.ReadToEnd()
                End Using
            Catch ex As Exception
                TextBlock1.Text = "Error occurred reading the file. " + ex.Message
            End Try
        Else
            TextBlock1.Text = "User did not pick a file"
        End If
    End Sub
    

Converting from a .NET Framework stream to a Windows Runtime stream

You can convert from a .NET Framework stream to a Windows Runtime stream by using one of the following System.IO.WindowsRuntimeStreamExtensions methods:

`System.IO.WindowsRuntimeStreamExtensions.AsInputStream`

Converts a managed stream in the .NET for Windows Store apps subset to an input stream in the Windows Runtime.

`System.IO.WindowsRuntimeStreamExtensions.AsOutputStream`

Converts a managed stream in the .NET for Windows Store apps subset to an output stream in the Windows Runtime.

AsRandomAccessStream
Converts a managed stream in the .NET for Windows Store apps subset to a random-access stream that can be used for reading or writing in the Windows Runtime.

When you convert a .NET Framework stream to a Windows Runtime stream, the capabilities of the converted stream will depend on the original stream. For example, if the original stream supports both reading and writing, and you call System.IO.WindowsRuntimeStreamExtensions.AsInputStream to convert the stream, the returned type will be an IRandomAccessStream, which implements IInputStream and IOutputStream, and supports reading and writing

.NET Framework streams do not support cloning, even after conversion. This means that if you convert a .NET Framework stream to a Windows Runtime stream and call GetInputStreamAt or GetOutputStreamAt, which call CloneStream or call CloneStream directly, an exception will occur.

To convert from a .NET Framework stream to a Windows Runtime random-access stream

  • Use the AsRandomAccessStream method, as shown in the following example.

    Important

    Ensure that the .NET Framework stream you are using supports seeking, or copy it to a stream that does. You can use the Stream.CanSeek property to determine this.

    To run this example, you must create a Windows Store XAML app that targets the .NET Framework 4.5.1 and contains a text block named TextBlock2 and a button named Button2. The button click event must be associated with the button2_Click method shown in this example.

    using System;
    using System.IO;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media.Imaging;
    using Windows.Storage;
    using System.Net.Http;
    using Windows.Storage.Pickers;
    
    Imports System.IO
    Imports System.Runtime.InteropServices.WindowsRuntime
    Imports Windows.UI.Xaml
    Imports Windows.UI.Xaml.Controls
    Imports Windows.UI.Xaml.Media.Imaging
    Imports Windows.Storage
    Imports System.Net.Http
    Imports Windows.Storage.Pickers
    
    private async void button2_Click(object sender, RoutedEventArgs e)
    {
    
        // Create an HttpClient and access an image as a stream.
        var client = new HttpClient();
        Stream stream = await client.GetStreamAsync("http://www.visualstudio.com/IC691934.png");
        // Create a .NET memory stream.
        var memStream = new MemoryStream();
    
        // Convert the stream to the memory stream, because a memory stream supports seeking.
        await stream.CopyToAsync(memStream);
    
        // Set the start position.
        memStream.Position = 0;
    
        // Create a new bitmap image.
        var bitmap = new BitmapImage();
    
        // Set the bitmap source to the stream, which is converted to a IRandomAccessStream.
        bitmap.SetSource(memStream.AsRandomAccessStream());
    
        // Set the image control source to the bitmap.
        image1.Source = bitmap;
    }
    
    Private Async Sub button2_Click(sender As Object, e As RoutedEventArgs)
    
    
        ' Create an HttpClient and access an image as a stream.
        Dim client = New HttpClient()
        Dim stream As Stream = Await client.GetStreamAsync("http://www.visualstudio.com/IC691934.png")
        ' Create a .NET memory stream.
        Dim memStream = New MemoryStream()
    
        ' Convert the stream to the memory stream, because a memory stream supports seeking.
        Await stream.CopyToAsync(memStream)
    
        ' Set the start position.
        memStream.Position = 0
    
        ' Create a new bitmap image.
        Dim bitmap = New BitmapImage()
    
        ' Set the bitmap source to the stream, which is converted to a IRandomAccessStream.
        bitmap.SetSource(memStream.AsRandomAccessStream())
    
        ' Set the image control source to the bitmap.
        image1.Source = bitmap
    End Sub
    

See Also

Quickstart: Reading and writing a file (Windows)
.NET for Windows Store apps overview
.NET for Windows Store apps – supported APIs