This post was most recently updated on April 18th, 2024.
3 min read.This article explains how to read and write files in a MAUI application. No, not AppPackageFiles, nobody likes those, but actual NORMAL files. Real files. Dynamic files. Files that can change. Runtime files.
I don’t know what to call them. But I hope you get the idea. Someone needs to document this stuff for other people only now starting with MAUI, right? 😀
Background
Lately, I’ve been playing around with MAUI a bit. You run into all kinds of things for building PoCs.
Anyway – I needed to write a file to disk and read it later. How do you do that with MAUI, though?
I could find a lot of instructions on how to read AppPackageFiles, and some misleading and non-functioning (probably meant for earlier versions of Xamarin.Forms or MAUI?) ways, but I needed something that works in .NET 7.
Solution
Ok. Let’s figure out how to do this!
Long story short, System.IO.File.OpenWrite
is the way to go.
This probably works for whatever MAUI version shipped with .NET 7 RTM version. Or maybe RC2? Maybe even earlier ones, and definitely probably newer ones.
Man, keeping up with the versioning is not easy. Fun times. But let’s get to it, shall we?
Time needed: 10 minutes
How to work with writeable files in .NET MAUI?
- Define your file name
Okay, so first of all, I’ll define whatever file we want to store. I’ll call mine “nappistate.txt” because of reasons.
private static string mainDir = FileSystem.Current.AppDataDirectory;
private static string fileName = "nappistate.txt";
private static string filePath = System.IO.Path.Combine(mainDir, fileName);
Ok. That’s a great beginning. But what are these variables going to do for us? - Figure out where this stuff is saved.
Now we’ll figure out where this stuff gets stored. For MAUI apps, the AppDataDirectory is not going to be under /bin. Nope, not at all! It’s in the only-a-bit-convoluted UWP packaged app folder structure –
You’ll occasionally see something like FileSystem.AppDataDirectory. That is probably something you need to implement yourselves or something or something that worked before – but it might not anymore, especially if you’re messing with Xamarin.Essentials or something.
Anyway – the path to your app directory is going to be something like this: - (OPTIONAL:) Find your saved file
This obviously works only after you’ve already run the code to save something. But essentially, you’ll just navigate to the path you could see when debugging.
And there it is: - Add your super special extra secret file storage provider dependency!
Just kidding! No extra dependencies. No community kits to install. No platform-specific implementations. It’s all available from System.IO directly!
In your code, you can use System.IO.OpenRead and System.IO.OpenWrite to open a filestream, and pass it on to StreamReader or StreamWriter, depending on what you’re trying to do. - Now read and write from the file!
Ok – code samples make this easier to understand. Say you want to read stuff from this file on your app’s startup. You can do something like this:private static async Task<string> ReadFile()
{
try
{
using Stream fileStream = System.IO.File.OpenRead(filePath);
using StreamReader reader = new StreamReader(fileStream);
var c = await reader.ReadToEndAsync();
return c;
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
return new List<NappiObject>();
}
And if you want to write to the file? Something like this should work:public static async Task SaveState(string str)
{
using FileStream outputStream = System.IO.File.OpenWrite(filePath);
using StreamWriter streamWriter = new StreamWriter(outputStream);
await streamWriter.WriteAsync(str);
}
Below, I’ll paste one possible implementation:
private static string mainDir = FileSystem.Current.AppDataDirectory;
private static string fileName = "nappistate.txt";
private static string filePath = System.IO.Path.Combine(mainDir, fileName);
private static async Task<str> ReadFile()
{
try
{
using Stream fileStream = System.IO.File.OpenRead(filePath);
using StreamReader reader = new StreamReader(fileStream);
var c = await reader.ReadToEndAsync();
return c;
}
catch (Exception ex)
{
// Handle this as you will
}
return String.Empty;
}
References
- “Performing cleanup” – Excel is stuck with an old, conflicted file and will never recover. - November 12, 2024
- How to add multiple app URIs for your Entra app registration? - November 5, 2024
- How to access Environment Secrets with GitHub Actions? - October 29, 2024