Como converter entre fluxos de .NET Framework e Windows Runtime (somente Windows)

.NET Framework para aplicativos UWP é um subconjunto do .NET Framework completo. Devido a requisitos de segurança e outros requisitos dos aplicativos UWP, não é possível usar o conjunto completo de APIs do .NET Framework para abrir e ler arquivos. Para obter mais informações, confira Visão geral do .NET para aplicativos UWP. No entanto, talvez você queira usar APIs do .NET Framework para outras operações de manipulação de fluxos. Para manipular esses fluxos, você pode converter entre um .NET Framework tipo de fluxo, como MemoryStream ou FileStream , e um fluxo de Windows Runtime, como IInputStream , IOutputStream ou IRandomAccessStream .

A classe System.IO.WindowsRuntimeStreamExtensions contém métodos que tornam fáceis essas conversões. No entanto, as diferenças subjacentes entre os fluxos do .NET Framework e os fluxos do Windows Runtime afetam os resultados do uso desses métodos, conforme descrito nas seguintes seções:

Converter um fluxo do Windows Runtime em um fluxo do .NET Framework

Para converter de um fluxo do Windows Runtime para um fluxo do .NET Framework, use um dos seguintes métodos System.IO.WindowsRuntimeStreamExtensions:

O Windows Runtime oferece tipos de fluxo que dão suporte ao acesso somente leitura, somente gravação ou de leitura e gravação. Essas funcionalidades são mantidas quando você converte um fluxo do Windows Runtime em um fluxo do .NET Framework. Além disso, se você converter um fluxo do Windows Runtime para um fluxo do .NET Framework e convertê-lo de volta, você obterá instância original do Windows Runtime outra vez.

É recomendável usar o método de conversão que corresponde aos recursos do fluxo de Windows Runtime que você deseja converter. No entanto, como IRandomAccessStream é legível e gravável (implementa IOutputStream e IInputStream), os métodos de conversão mantêm as funcionalidades do fluxo original. Por exemplo, o uso de WindowsRuntimeStreamExtensions.AsStreamForRead para converter um IRandomAccessStream não limita o fluxo convertido do .NET Framework a ser legível. Ele também é gravável.

Exemplo: Converter Windows Runtime acesso aleatório para .NET Framework Stream

Para converter de um fluxo de acesso aleatório do Windows Runtime para um fluxo do .NET Framework, use o método WindowsRuntimeStreamExtensions.AsStream.

O exemplo de código a seguir solicita que você selecione um arquivo, abre-o com as APIs do Windows Runtime e, em seguida, converte-o em um fluxo do .NET Framework. Ele lê o fluxo e os coloca em um bloco de texto. Você normalmente manipulará o fluxo com as APIs do .NET Framework antes de produzir os resultados.

Para executar esse exemplo, crie um aplicativo UWP XAML que contém um bloco de texto chamado TextBlock1 e um botão chamado Button1. Associe o evento de clique no botão ao método button1_Click mostrado no exemplo.

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;

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";
    }
}
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 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

Converter um fluxo do .NET Framework em um fluxo do Windows Runtime

Para converter de um fluxo do .NET Framework para um fluxo do Windows Runtime, use um dos seguintes métodos System.IO.WindowsRuntimeStreamExtensions:

Quando você converte um fluxo do .NET Framework em um fluxo do Windows Runtime, as funcionalidades do fluxo convertido dependem do fluxo original. Por exemplo, se o fluxo original tiver suporte à leitura e à gravação e você chamar WindowsRuntimeStreamExtensions.AsInputStream para converter o fluxo, o tipo retornado será um IRandomAccessStream. IRandomAccessStream implementa IInputStream e IOutputStream e dá suporte à leitura e à gravação.

Os fluxos do .NET Framework não dão suporte à clonagem, mesmo após a conversão. Se você converte um fluxo do .NET Framework em um fluxo do Windows Runtime e chama GetInputStreamAt ou GetOutputStreamAt, que chama CloneStream, ou se você chama CloneStream diretamente, ocorre uma exceção.

Exemplo: converter .NET Framework em Windows Runtime fluxo de acesso aleatório

Para converter um fluxo do .NET Framework em um fluxo de acesso aleatório do Windows Runtime, use o método AsRandomAccessStream, conforme mostrado no seguinte exemplo:

Importante

Verifique se o fluxo do .NET Framework que você está usando dá suporte à busca ou copie-o para um fluxo que dê esse suporte. Você pode usar a propriedade Stream.CanSeek para determinar isso.

Para executar esse exemplo, crie um aplicativo UWP XAML direcionado ao .NET Framework 4.5.1 e que contém um bloco de texto chamado TextBlock2 e um botão chamado Button2. Associe o evento de clique no botão ao método button2_Click mostrado no exemplo.

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;

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("https://docs.microsoft.com/en-us/dotnet/images/hub/featured-1.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;
}
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 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("https://docs.microsoft.com/en-us/dotnet/images/hub/featured-1.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

Consulte também