重要的 API
使用 StorageFile 对象读取和写入文件。
注释
有关完整示例,请参阅 文件访问示例。
先决条件
了解 WinUI 应用的异步编程
了解如何使用 C# 编写异步应用,请参阅 在 C# 或 Visual Basic 中调用异步 API。 若要了解如何使用 C++/WinRT 编写异步应用,请参阅 使用 C++/WinRT 的并发和异步操作。
了解如何获取你要读取、写入或同时进行这两项操作的文件
您可以在“使用选取器打开文件和文件夹”中学习如何使用文件选取器来获取文件。
创建文件
下面介绍如何在应用的本地文件夹中创建文件。 如果已存在,我们将替换它。
// Create sample file; replace if exists.
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile =
await storageFolder.CreateFileAsync("sample.txt",
Windows.Storage.CreationCollisionOption.ReplaceExisting);
// MainPage.h
#include <winrt/Windows.Storage.h>
...
Windows::Foundation::IAsyncAction ExampleCoroutineAsync()
{
// Create a sample file; replace if exists.
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
co_await storageFolder.CreateFileAsync(L"sample.txt", Windows::Storage::CreationCollisionOption::ReplaceExisting);
}
写入文件
下面介绍如何使用 StorageFile 类写入磁盘上的可写文件。 写入文件的每个方法(除非在创建文件后立即写入文件)的常见第一步是使用 StorageFolder.GetFileAsync 获取文件。
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile =
await storageFolder.GetFileAsync("sample.txt");
// MainPage.h
#include <winrt/Windows.Storage.h>
...
Windows::Foundation::IAsyncAction ExampleCoroutineAsync()
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFile{ co_await storageFolder.CreateFileAsync(L"sample.txt", Windows::Storage::CreationCollisionOption::ReplaceExisting) };
// Process sampleFile
}
将文本写入文件
通过调用 FileIO.WriteTextAsync 方法将文本写入文件。
await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "Swift as a shadow");
// MainPage.h
#include <winrt/Windows.Storage.h>
...
Windows::Foundation::IAsyncAction ExampleCoroutineAsync()
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") };
// Write text to the file.
co_await Windows::Storage::FileIO::WriteTextAsync(sampleFile, L"Swift as a shadow");
}
使用缓冲区将字节写入文件(2 个步骤)
首先,调用 CryptographicBuffer.ConvertStringToBinary 以获取要写入文件的字节(基于字符串)的缓冲区。
var buffer = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary( "What fools these mortals be", Windows.Security.Cryptography.BinaryStringEncoding.Utf8);// MainPage.h #include <winrt/Windows.Security.Cryptography.h> #include <winrt/Windows.Storage.h> #include <winrt/Windows.Storage.Streams.h> ... Windows::Foundation::IAsyncAction ExampleCoroutineAsync() { Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() }; auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") }; // Create the buffer. Windows::Storage::Streams::IBuffer buffer{ Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary( L"What fools these mortals be", Windows::Security::Cryptography::BinaryStringEncoding::Utf8)}; // The code in step 2 goes here. }然后,通过调用 FileIO.WriteBufferAsync 方法将字节从缓冲区写入文件。
await Windows.Storage.FileIO.WriteBufferAsync(sampleFile, buffer);co_await Windows::Storage::FileIO::WriteBufferAsync(sampleFile, buffer);
使用流将文本写入文件(4 个步骤)
首先,通过调用 StorageFile.OpenAsync 方法打开文件。 打开操作完成后,它将返回文件内容的流。
var stream = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);// MainPage.h #include <winrt/Windows.Storage.h> #include <winrt/Windows.Storage.Streams.h> ... Windows::Foundation::IAsyncAction ExampleCoroutineAsync() { Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() }; auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") }; Windows::Storage::Streams::IRandomAccessStream stream{ co_await sampleFile.OpenAsync(Windows::Storage::FileAccessMode::ReadWrite) }; // The code in step 2 goes here. }接下来,通过从中调用
stream方法获取输出流。 如果使用的是 C#,请将它括在 using 语句中,以管理输出流的生存期。 如果使用 C++/WinRT,则可以通过将其放在块的范围内来控制其生命周期,或者在不再使用时将其设置为nullptr。using (var outputStream = stream.GetOutputStreamAt(0)) { // We'll add more code here in the next step. } stream.Dispose(); // Or use the stream variable (see previous code snippet) with a using statement as well.Windows::Storage::Streams::IOutputStream outputStream{ stream.GetOutputStreamAt(0) }; // The code in step 3 goes here.现在,添加此代码(如果使用 C#,请在现有的 using 语句中),以通过创建一个新的 DataWriter 对象并调用 DataWriter.WriteString 方法来写入输出流。
using (var dataWriter = new Windows.Storage.Streams.DataWriter(outputStream)) { dataWriter.WriteString("DataWriter has methods to write to various types, such as DataTimeOffset."); }Windows::Storage::Streams::DataWriter dataWriter; dataWriter.WriteString(L"DataWriter has methods to write to various types, such as DataTimeOffset."); // The code in step 4 goes here.最后,添加此代码(如果使用 C#,在内部 using 语句中)以使用 DataWriter.StoreAsync 将文本保存到文件中,并使用 IOutputStream.FlushAsync 关闭流。
await dataWriter.StoreAsync(); await outputStream.FlushAsync();dataWriter.StoreAsync(); outputStream.FlushAsync();
写入文件的最佳做法
有关其他详细信息和最佳做法指南,请参阅 有关写入文件的最佳做法。
从文件中读取
下面介绍如何使用 StorageFile 类从磁盘上的文件读取数据。 从文件读取的每个方法的常见第一步是使用 StorageFolder.GetFileAsync 获取文件。
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile =
await storageFolder.GetFileAsync("sample.txt");
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") };
// Process file
从文件读取文本
通过调用 FileIO.ReadTextAsync 方法从文件读取文本。
string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);
Windows::Foundation::IAsyncOperation<winrt::hstring> ExampleCoroutineAsync()
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") };
co_return co_await Windows::Storage::FileIO::ReadTextAsync(sampleFile);
}
使用缓冲区从文件读取文本(2 个步骤)
首先,调用 FileIO.ReadBufferAsync 方法。
var buffer = await Windows.Storage.FileIO.ReadBufferAsync(sampleFile);Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() }; auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") }; Windows::Storage::Streams::IBuffer buffer{ co_await Windows::Storage::FileIO::ReadBufferAsync(sampleFile) }; // The code in step 2 goes here.然后使用 DataReader 对象先读取缓冲区的长度及其内容。
using (var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(buffer)) { string text = dataReader.ReadString(buffer.Length); }auto dataReader{ Windows::Storage::Streams::DataReader::FromBuffer(buffer) }; winrt::hstring bufferText{ dataReader.ReadString(buffer.Length()) };
使用流从文件读取文本(4 个步骤)
通过调用 StorageFile.OpenAsync 方法打开文件的流。 当操作完成时,它将返回文件的内容的流。
var stream = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.Read);Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() }; auto sampleFile{ co_await storageFolder.GetFileAsync(L"sample.txt") }; Windows::Storage::Streams::IRandomAccessStream stream{ co_await sampleFile.OpenAsync(Windows::Storage::FileAccessMode::Read) }; // The code in step 2 goes here.获取稍后要使用的流的大小。
ulong size = stream.Size;uint64_t size{ stream.Size() }; // The code in step 3 goes here.通过调用 IRandomAccessStream.GetInputStreamAt 方法获取输入流。 将此放入 using 语句中,以管理流的生存期。 调用 GetInputStreamAt 将位置设置为流的开头时,请指定 0。
using (var inputStream = stream.GetInputStreamAt(0)) { // We'll add more code here in the next step. }Windows::Storage::Streams::IInputStream inputStream{ stream.GetInputStreamAt(0) }; Windows::Storage::Streams::DataReader dataReader{ inputStream }; // The code in step 4 goes here.最后,在现有 using 语句中添加此代码,以获取流上的 DataReader 对象,然后通过调用 DataReader.LoadAsync 和 DataReader.ReadString 读取文本。
using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream)) { uint numBytesLoaded = await dataReader.LoadAsync((uint)size); string text = dataReader.ReadString(numBytesLoaded); }unsigned int cBytesLoaded{ co_await dataReader.LoadAsync(size) }; winrt::hstring streamText{ dataReader.ReadString(cBytesLoaded) };