• 了解通用 Windows 平台 (UWP) 应用的异步编程

    若要了解如何使用 C# 或 Visual Basic 编写异步应用,请参阅 使用 C# 或 Visual Basic 调用异步 API 。 若要了解如何在 C++/WinRT 中编写异步应用,请参阅 借助 C++/WinRT 的并发和异步操作 。 若要了解如何使用 C++/CX 编写异步应用,请参阅 使用 C++/CX 进行异步编程

  • 了解如何获取你希望读取和/或写入的文件

    可以在 使用选取器打开文件和文件夹 中了解如何使用文件选取器获取文件。

    这里介绍了如何在应用的本地文件夹中创建一个文件。 如果文件存在,我们将替换它。

    // 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);
    
    // Create a sample file; replace if exists.
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    concurrency::create_task(storageFolder->CreateFileAsync("sample.txt", CreationCollisionOption::ReplaceExisting));
    
    ' Create sample file; replace if exists.
    Dim storageFolder As StorageFolder = Windows.Storage.ApplicationData.Current.LocalFolder
    Dim sampleFile As StorageFile = Await storageFolder.CreateFileAsync("sample.txt", 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
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile) 
        // Process file
    
    Dim storageFolder As StorageFolder = Windows.Storage.ApplicationData.Current.LocalFolder
    Dim sampleFile As StorageFile = Await storageFolder.GetFileAsync("sample.txt")
    

    将文本写入文件

    通过调用 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");
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile) 
        //Write text to a file
        create_task(FileIO::WriteTextAsync(sampleFile, "Swift as a shadow"));
    
    Await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "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.
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        // Create the buffer
        IBuffer^ buffer = CryptographicBuffer::ConvertStringToBinary
        ("What fools these mortals be", BinaryStringEncoding::Utf8);
    
    Dim buffer = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(
        "What fools these mortals be",
        Windows.Security.Cryptography.BinaryStringEncoding.Utf8)
    
  • 然后,通过调用 FileIO.WriteBufferAsync 方法,将字节从缓冲区写入文件 。

    await Windows.Storage.FileIO.WriteBufferAsync(sampleFile, buffer);
    
    co_await Windows::Storage::FileIO::WriteBufferAsync(sampleFile, buffer);
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        // Create the buffer
        IBuffer^ buffer = CryptographicBuffer::ConvertStringToBinary
        ("What fools these mortals be", BinaryStringEncoding::Utf8);      
        // Write bytes to a file using a buffer
        create_task(FileIO::WriteBufferAsync(sampleFile, buffer));
    
    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.
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        create_task(sampleFile->OpenAsync(FileAccessMode::ReadWrite)).then([sampleFile](IRandomAccessStream^ stream)
            // Process stream
    
    Dim stream = Await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite)
    
  • 接下来,通过从 stream 调用 IRandomAccessStream.GetOutputStreamAt 方法获取输出流 。 如果你使用的是 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.
    
    // Add to "Process stream" in part 1
    IOutputStream^ outputStream = stream->GetOutputStreamAt(0);
    
    Using outputStream = stream.GetOutputStreamAt(0)
    ' We'll add more code here in the next step.
    End Using
    
  • 现在,添加此代码(如果你使用的是 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.
    
    // Added after code from part 2
    DataWriter^ dataWriter = ref new DataWriter(outputStream);
    dataWriter->WriteString("DataWriter has methods to write to various types, such as DataTimeOffset.");
    
    Dim dataWriter As New DataWriter(outputStream)
    dataWriter.WriteString("DataWriter has methods to write to various types, such as DataTimeOffset.")
    
  • 最后,添加此代码(如果你使用的是 C#,在内部 using 语句中)以使用 DataWriter.StoreAsync 将文本保存到你的文件并使用 IOutputStream.FlushAsync 关闭该流 。

    await dataWriter.StoreAsync();
    await outputStream.FlushAsync();
    
    dataWriter.StoreAsync();
    outputStream.FlushAsync();
    
    // Added after code from part 3
    dataWriter->StoreAsync();
    outputStream->FlushAsync();
    
    Await dataWriter.StoreAsync()
    Await 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
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        // Process file
    
    Dim storageFolder As StorageFolder = Windows.Storage.ApplicationData.Current.LocalFolder
    Dim sampleFile As StorageFile = Await storageFolder.GetFileAsync("sample.txt")
    

    从文件读取文本

    通过调用 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);
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        return FileIO::ReadTextAsync(sampleFile);
    
    Dim text As String = 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.
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        return FileIO::ReadBufferAsync(sampleFile);
    }).then([](Streams::IBuffer^ buffer)
        // Process buffer
    
    Dim buffer = Await Windows.Storage.FileIO.ReadBufferAsync(sampleFile)
    
  • 然后,使用 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()) };
    
    // Add to "Process buffer" section from part 1
    auto dataReader = DataReader::FromBuffer(buffer);
    String^ bufferText = dataReader->ReadString(buffer->Length);
    
    Dim dataReader As DataReader = Windows.Storage.Streams.DataReader.FromBuffer(buffer)
    Dim text As String = 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.
    
    StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
    create_task(storageFolder->GetFileAsync("sample.txt")).then([](StorageFile^ sampleFile)
        create_task(sampleFile->OpenAsync(FileAccessMode::Read)).then([sampleFile](IRandomAccessStream^ stream)
            // Process stream
    
    Dim stream = Await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.Read)
    
  • 获取稍后要使用的流的大小。

    ulong size = stream.Size;
    
    uint64_t size{ stream.Size() };
    // The code in step 3 goes here.
    
    // Add to "Process stream" from part 1
    UINT64 size = stream->Size;
    
    Dim size = stream.Size
    
  • 通过调用 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.
    
    // Add after code from part 2
    IInputStream^ inputStream = stream->GetInputStreamAt(0);
    auto dataReader = ref new DataReader(inputStream);
    
    Using inputStream = stream.GetInputStreamAt(0)
    ' We'll add more code here in the next step.
    End Using
    
  • 最后,将此代码添加到现有的 using 语句中以在流上获取 DataReader 对象,然后通过调用 DataReader.LoadAsyncDataReader.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) };
    
    // Add after code from part 3
    create_task(dataReader->LoadAsync(size)).then([sampleFile, dataReader](unsigned int numBytesLoaded)
        String^ streamText = dataReader->ReadString(numBytesLoaded);
    
    Dim dataReader As New DataReader(inputStream)
    Dim numBytesLoaded As UInteger = Await dataReader.LoadAsync(CUInt(size))
    Dim text As String = dataReader.ReadString(numBytesLoaded)
    
  • 向文件进行写入的最佳做法
  •