WinRT封装了简单流API,比如FileIO:
public static class FileIO {
public static IAsyncAction WriteBytesAsync(IStorageFile file, Byte[] buffer);
public static IAsyncAction WriteBufferAsync(IStorageFile file, IBuffer buffer);
public static IAsyncOperation<IBuffer> ReadBufferAsync(IStorageFile file);
public static IAsyncAction WriteLinesAsync(IStorageFile file, IEnumerable<String> lines);
public static IAsyncAction AppendLinesAsync(IStorageFile file, IEnumerable<String> lines);
public static IAsyncOperation<IList<String>> ReadLinesAsync(IStorageFile file);
public static IAsyncAction WriteTextAsync(IStorageFile file, String contents);
public static IAsyncAction AppendTextAsync(IStorageFile file, String contents);
public static IAsyncOperation<String> ReadTextAsync(IStorageFile file);
}
前3个函数是传输字节数组的。剩下的是传输文本的。文本可以通过编码成字节。后6个函数都把文本转换成字节(UTF-8),当然还有其他格式的重载。
下面的代码创建文件,并写入数据:
// Create a file:
StorageFile file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("MyFile.txt");
// Write 2 lines of text to the file (encoded with UTF-8):
String[] output = new[] { "This is line 1", "This is line 2" };
await FileIO.WriteLinesAsync(file, output);
// Read the lines of text from the file (decoded with UTF-8):
IList<String> input = await FileIO.ReadLinesAsync(file);
WinRT还提供了一个PathIO类,唯一的区别是操作系统前必须已经创建文件,换成它就是这样:
// NOTE: You MUST create the file before writing to it:
StorageFile file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("MyFile.txt");
// Write 2 lines of text to the file (encoded with UTF-8):
String[] output = new[] { "This is line 1", "This is line 2" };
await PathIO.WriteLinesAsync(file.Path, output);
// Read the lines of text from the file (decoded with UTF-8):
IList<String> input = await PathIO.ReadLinesAsync(file.Path);
注意:所有的I/O操作都实现成异步的,因为IClosable的函数是Close而不是CloseAsync,Close函数中不能执行IO操作。这与.net的Dispose的原理不一样。在Dispose中可以调用IO操作,调用Dispose操作会引起IO,缓存数据在设备关闭前写到设备上。但是在WinRT上,调用Dispose不会执行IO操作,而且可能会丢数据。必须要注意显式地Flush。
IInputStream的ReadAsync和IOutputStream的WriteAsync用于读写stream。
IOutputStream还有一个FlushAsync,一般情况下,当buffer填满时,Windows会自动写入设备。但重要数据需要用这个函数减少数据丢失的概率。但是频繁调用会影响效率。
IOutputStream和IOutputStream可以顺序读写不知道长度的Stream,比如网络流。
IRandomAccessStream可以随机读写Stream。可以用Seek函数定位开始位置。GetInputStreamAt或GetOutputStreamAt也可以定位偏移量。
注意:并发读写可能导致不可预料的后果。
也可以简单地用IStorageFile的OpenAsync打开文件,获取一个IRandomAccessStream,然后用ReadAsync和WriteAsync读写,然后调用Dispose让它被垃圾回收。
IRandomAccessStream用于StorageFile,图片,位图,缩略图,多媒体,和InMemoryRandomAccessStream类。
IInputStream接口用于后台传输,以及DataReader, DataProtectionProvider, Decompressor, 和AtomPubClient。
IOutputStream用于网络流,以及 DataWriter, DataProtectionProvider,Compressor, 和 InkManager 类。
.NET与WinRT的IO接口用下面的方式互操作:
namespace System.IO { // Defined in System.Runtime.WindowsRuntime.dll
public static class WindowsRuntimeStorageExtensions {
public static Task<Stream> OpenStreamForReadAsync(this IStorageFile file);
public static Task<Stream> OpenStreamForWriteAsync(this IStorageFile file);
public static Task<Stream> OpenStreamForReadAsync(this IStorageFolder rootDirectory,
String relativePath);
public static Task<Stream> OpenStreamForWriteAsync(this IStorageFolder rootDirectory,
String relativePath, CreationCollisionOption creationCollisionOption);
}
}
和
namespace System.IO { // Defined in System.Runtime.WindowsRuntime.dll
public static class WindowsRuntimeStreamExtensions {
public static Stream AsStream(this IRandomAccessStream winRTStream);
public static Stream AsStream(this IRandomAccessStream winRTStream, Int32 bufferSize);
public static Stream AsStreamForRead(this IInputStream winRTStream);
public static Stream AsStreamForRead(this IInputStream winRTStream, Int32 bufferSize);
public static Stream AsStreamForWrite(this IOutputStream winRTStream);
public static Stream AsStreamForWrite(this IOutputStream winRTStream, Int32 bufferSize);
public static IInputStream AsInputStream (this Stream netStream);
public static IOutputStream AsOutputStream(this Stream netStream);
public static IRandomAccessStream AsRandomAccessStream(this Stream netStream);
}
}