Create, write, and read a file
Important APIs
Read and write a file using a StorageFile object.
Note
For a complete sample, see the File access sample.
Prerequisites
Understand async programming for Universal Windows Platform (UWP) apps
You can learn how to write asynchronous apps in C# or Visual Basic, see Call asynchronous APIs in C# or Visual Basic. To learn how to write asynchronous apps in C++/WinRT, see Concurrency and asynchronous operations with C++/WinRT. To learn how to write asynchronous apps in C++/CX, see Asynchronous programming in C++/CX.
Know how to get the file that you want to read from, write to, or both
You can learn how to get a file by using a file picker in Open files and folders with a picker.
Creating a file
Here's how to create a file in the app's local folder. If it already exists, we replace it.
// 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)
Writing to a file
Here's how to write to a writable file on disk using the StorageFile class. The common first step for each of the ways of writing to a file (unless you're writing to the file immediately after creating it) is to get the file with 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")
Writing text to a file
Write text to your file by calling the FileIO.WriteTextAsync method.
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")
Writing bytes to a file by using a buffer (2 steps)
First, call CryptographicBuffer.ConvertStringToBinary to get a buffer of the bytes (based on a string) that you want to write to your file.
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)
Then write the bytes from your buffer to your file by calling the FileIO.WriteBufferAsync method.
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)
Writing text to a file by using a stream (4 steps)
First, open the file by calling the StorageFile.OpenAsync method. It returns a stream of the file's content when the open operation completes.
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)
Next, get an output stream by calling the IRandomAccessStream.GetOutputStreamAt method from the
stream
. If you're using C#, then enclose this in a using statement to manage the output stream's lifetime. If you're using C++/WinRT, then you can control its lifetime by enclosing it in a block, or setting it tonullptr
when you're done with it.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
Now add this code (if you're using C#, within the existing using statement) to write to the output stream by creating a new DataWriter object and calling the DataWriter.WriteString method.
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.")
Lastly, add this code (if you're using C#, within the inner using statement) to save the text to your file with DataWriter.StoreAsync and close the stream with 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()
Best practices for writing to a file
For additional details and best practice guidance, see Best practices for writing to files.
Reading from a file
Here's how to read from a file on disk using the StorageFile class. The common first step for each of the ways of reading from a file is to get the file with 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")
Reading text from a file
Read text from your file by calling the FileIO.ReadTextAsync method.
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)
Reading text from a file by using a buffer (2 steps)
First, call the FileIO.ReadBufferAsync method.
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)
Then use a DataReader object to read first the length of the buffer and then its contents.
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)
Reading text from a file by using a stream (4 steps)
Open a stream for your file by calling the StorageFile.OpenAsync method. It returns a stream of the file's content when the operation completes.
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)
Get the size of the stream to use later.
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
Get an input stream by calling the IRandomAccessStream.GetInputStreamAt method. Put this in a using statement to manage the stream's lifetime. Specify 0 when you call GetInputStreamAt to set the position to the beginning of the stream.
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
Lastly, add this code within the existing using statement to get a DataReader object on the stream then read the text by calling DataReader.LoadAsync and 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)