如何:在 .NET Framework 和 Windows 运行时流之间进行转换(仅限 Windows)

适用于 UWP 应用的 .NET Framework 是完整的 .NET Framework 的子集。 由于 UWP 应用的安全性和其他要求,你无法使用整套 .NET Framework API 来打开和读取文件。 有关详细信息,请参阅适用于 UWP 应用的 .NET 概述。 但是,你可能需要将 .NET Framework API 用于其他流处理操作。 若要操作这些流,可以在 .NET Framework 流类型(如 MemoryStreamFileStream)和 Windows 运行时流(如 IInputStreamIOutputStreamIRandomAccessStream)之间进行转换。

System.IO.WindowsRuntimeStreamExtensions 类包含简化这些转换的方法。 但是,.NET Framework 与 Windows 运行时流之间存在一些基本差异,这将影响使用这些方法所获得的结果,如以下部分中所述:

从 Windows 运行时流转换为 .NET Framework 流

若要从 Windows 运行时流转换为 .NET Framework 流,请使用以下 System.IO.WindowsRuntimeStreamExtensions 方法之一:

Windows 运行时提供支持只读、只写或读写的流类型。 如果将 Windows 运行时流转换为 .NET Framework 流,这些功能将保留。 此外,如果你在 Windows 运行时流与 .NET Framework 流之间转换,则将取回原始 Windows 运行时实例。

最佳做法是使用与要转换的 Windows 运行时流的功能匹配的转换方法。 但是,由于 IRandomAccessStream 是可读写的(它同时实现了 IOutputStreamIInputStream),因此转换方法将保留原始流的功能。 例如,使用 WindowsRuntimeStreamExtensions.AsStreamForRead 转换 IRandomAccessStream 不会限制转换的 .NET Framework 流的可读性。 它也是可写的。

示例:将 Windows 运行时随机访问流转换为 .NET Framework 流

若要从 Windows 运行时随机访问流转换为 .NET Framework 流,请使用 WindowsRuntimeStreamExtensions.AsStream 方法。

下面的代码示例会提示用户选择文件,使用 Windows 运行时 API 将其打开,然后将其转换为 .NET Framework 流。 它可读取流,并将其输出为文本块。 在输出结果之前,通常使用 .NET Framework API 操作流。

// Create a file picker.
FileOpenPicker picker = new FileOpenPicker();
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)
    {
        // ...
    }
}       

从 .NET Framework 转换为 Windows 运行时流

若要从.NET Framework 流转换为 Windows 运行时流,请使用下列任一 System.IO.WindowsRuntimeStreamExtensions 方法:

在将 .NET Framework 流转换为 Windows 运行时流时,转换后的流的功能将取决于原始流。 例如,如果原始流支持读取和写入,并且你调用 WindowsRuntimeStreamExtensions.AsInputStream 来转换流,则返回的类型为 IRandomAccessStreamIRandomAccessStream 可实现 IInputStreamIOutputStream,且支持读取和写入。

.NET Framework 流不支持克隆,即使转换后也是如此。 如果将 .NET Framework 流转换为 Windows 运行时流,并调用 GetInputStreamAtGetOutputStreamAt(这会直接调用 CloneStreamCloneStream),则会引发异常。

示例:将 .NET Framework 转换为 Windows 运行时随机访问流

要从 .NET Framework 流转换为 Windows 运行时随机访问流,请使用 AsRandomAccessStream 方法,如以下示例所示:

重要

确保所使用的 .NET Framework 流支持查找或将其复制到支持查找的流。 可使用 Stream.CanSeek 属性来确定这一点。

// Create an HttpClient and access an image as a stream.
var client = new HttpClient();
Stream stream = await client.GetStreamAsync("https://learn.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;

请参阅