建立、寫入和讀取檔案
重要 API
使用 StorageFile 物件讀取和寫入檔案。
注意
如需完整範例,請參閱檔案存取範例 \(英文\)。
必要條件
了解通用 Windows 平台 (UWP) 應用程式的非同步程式設計
您可以參閱在 C# 或 Visual Basic 中呼叫非同步 API,以了解如何在 C# 或 Visual Basic 中撰寫非同步應用程式。 若要了解如何使用 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.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) };
// 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)