Working with files, and especially
saving files can be a hassle, especially across platforms. But not
anymore for .NET MAUI. In this video, we're going to learn how to
save files the easy way. Mobile devices and cross platform apps
and file systems... It can be a hassle if you have some
experience with it. You probably know what I'm talking about. And especially
with saving files, right, you have to to have the user pick a
location, what type of file actually save the file. Now with .NET MAUI and
the .NET MAUI Community Toolkit, we've made that super
easy. We now have the FileSaver API which allows you to do all of
this. Basically, in one operation, the user can pick a
location, save the file, the contents that you have prepared
from your application, it will be saved and you get the path as a return value. So
basically, what other thing can I do than just hop over to Visual
Studio and show you how to work with it? Welcome to Visual
Studio 2022. I just created a new .NET MAUI
application. And as always, you can find all the code in a GitHub repository
that is on my account. So find the link down below or just search for my
user on GitHub and you'll probably find it. So this is just a File, New project.
The thing that I already did is install the .NET MAUI
Community Toolkit. If I go over to my Solution Explorer,
you know how to do it, right? You right click on your project,
Manage NuGet Packages. I already installed the CommunityToolkit.Maui.
You can see it right here. And you will need to do a little bit
of initialization here with the UseMauiCommunityToolkit, you've watched
all my other videos. So you know how to do this, right? And you need to have
the using CommunityToolkit.Maui; for that, right here. So actually
for this one, let's do it the proper way. And we can use dependency
injection, right? So what we're going to do is say
builder.Services. Add... I can do this as a singleton, I
guess. So AddSingleton and I can say IFileSaver, you can see it. Here it is. It
lives in CommunityToolkit.Maui.Storage. And the one I want to
register is... FileSaver.Default right? So this kind of follows the
other APIs that we have in .NET MAUI where you have the default static
implementation of the FilePicker or the MediaPicker
and a bunch of other things. Geolocation,
they all have this kind of pattern. So you can register it like this. So we got
that set up and we need to have the builder.Services.
AddTransient for my MainPage. So I can use this
with the constructor injection, right? So now
it has all this, it knows about all my dependencies. I can go over to
my MainPage.xaml.cs and in my main page I can now here say
IFileSaver and I'll put that in a field,
I'm not going to use this count. So let's just replace this with
IFileSaver fileSaver. Naming is hard, so I'm not even going to try. And then
I have to say this.fileSaver = fileSaver and Visual
Studio already knows what's up. So it helps me with the IntelliSense
right here. So now I got this FileSaver that will be injected through
dependency injection. And I can use this to actually save my file.
So let's do that in this CounterClicked event right here. And what I
want to do is well, let's first explore what is
here. And it's actually just one thing. We just have the SaveAsync, but
there's a lot of power packed into this. So what you can do here is
set an initial path. So for an initial
path which is going to suggest the user like,
hey, this might be a good spot to save your file. I know this is not a
thing that is supported across all the platforms.
So make sure to check the documentation for any of this because I know for
Windows for instance, the initial path, you can't
set that to something custom. So it's probably not going to work perfectly
there, but it is there for you to configure if you
want to use it. Then we have the file name. So the file name that
you kind of want to suggest because they're still going to have this
dialog and put in their file name, right? And you can use the stream for
the contents that you're going to put in the file contents. And then
you have a cancellation token. And with a cancellation token, you can
cancel this operation from your application, right? So maybe you
have some kind of time out, a timer in your application. If they're not
going to save within 10 seconds, then everything will detonate and
you're going to cancel this operation. You can say CancellationToken.Cancel and
it will programmatically cancel the dialog and not continue any further.
Not going to focus on that. If that's something that you want to learn more
on, let me know down in the comments below. So this is also it has a couple
of overloads to make this kind of like simpler and
more verbose. So what I want to do first is probably
come up with some contents that I actually want to go save,
right? So what I want to do here is probably come up with a
stream. So I'm going to do a using because you have to clean up the
streams. And I'm going to say var stream = new and I'm just going to do a
MemoryStream. So this is a thing that's going to be in memory and then I can
say Encoding. So I'm just going to do a simple string, not
the Android encoding. We have multiple encodings
now. Welcome to cross-platform development. I just want to have the System.Text.Encoding Default.GetBytes because I want to get the bytes from this and I
can just put a string in here. So maybe something like, I don't
know... Have you subscribed to this amazing channel yet? I don't know, maybe you're
watching some YouTube channel and you think like, oh, you suddenly feel the urge
to click the subscribe button. This is your cue. So now I have a
simple string. But this of course can be an image, it can be
binary, it can be whatever you want to write in that file. I'm
just going to go with a simple text so I can use this now. And
now I can say var path =.... because this is going to save it, right? And this is going to return
me. I actually didn't show you that, but this is going to return a string,
which is the file path where it actually ended up saving this
file. So I want to make this async so that everything
is happy here and I can say for the file path is
subscribe.txt. And then I want to do the stream,
which is going to be stream. And I'm not going to really
use the cancellation token here. Else what I could do I could
probably still show you is CancellationTokenSource, cancellationTokenSource = new() so I can create a new one here and
then I can put this cancellationTokenSource in here, .Token, which is the actual not a token, is it a token? And now if I
would want to cancel, I could say cancellationTokenSource.Cancel(), right? So I could cancel it and then
the dialog would probably disappear and all magic things would happen. So you
could do this, or if you don't want to use this
functionality, you could just say default here and that will do basically this new
cancellation token inside of this thing. But you can't
reach it, so you're never going to use it, right? So I'll just leave it
for this so that it will end up in the GitHub repository
like this as well, so that you know how to work with this, if that's what
you want. And then let's go over to my XAML actually for a
little bit. So I'm going to reuse this hello world label just because it has
a nice big font and I'm going to say x:Name and I'm going to say
fileSaverResult, something like that. And I can use
this to actually put in the path here, right? So we can inspect what's going
on here. So I can set this text to path and we have that. Well, no, it's going to be... Oh, I
forgot the await here. So that's why it's not working. Okay, so now what is
going to happen actually just run it on Windows, it's going to create the
stream. It's going to give me a little
dialog, SaveAsync. So it's going to suggest
me subscribe.txt, which is probably fine. It's going to put the
stream in there and it's going to give me back the resulting file path. So if
I click here, I expect to see a little dialog here. It
already suggests me here subscribe.txt. I can go here to, I don't know,
Desktop, LikeAndSubscribe. That sounds like
something. So subscrib.txt, save it there. And you can see there's
a resulting path here in the UI, right? So C:\Users\my username\
Desktop\LikeAndSubscribe\ subscribe.txt. And whenever I pull up
a little Explorer window now here and go to my desktop to
LikeAndSubscribe, you can see this subscrib.txt. And whenever I
open it, it has written this contents that I've put in here.
Have you subscribed to this amazing channel
yet? So if you haven't the last time, then do it now. So this is how you can easily save files in your .NET MAUI
application. If you have been dealing with these
types of scenarios before, then you probably know that this is a great improvement
because this is just one, two, three lines of code depending on
how you count, this to save a file, to save these contents on a
custom location. Whereas if you had to do this before,
you had to write code to show the dialog, actually get the bytes
for your file, let the user pick a location, write a... A lot of
hassle, now one line of code in the .NET
MAUI Community Toolkit. There's a couple of important things
that I didn't show you. One is you want to wrap this in a try/catch
block. I will make sure that is in the code that ends up in the
GitHub repository below. Because if you cancel out of the dialog, then it
will throw an exception. So you want to make sure that your
application does not have an unhandled exception suddenly.
So use this for your validation scenarios to check if the user actually saved
something or canceled out of it. The other thing I didn't show you is
the permissions for Windows. You don't need to set up any additional permissions,
but for Android and Tizen I think you definitely do, which is all
described in the documentation. So make sure to check the documentation in the
link down in the video description below. That is all I have right now. Do you
see any room for improvements here? Do you like this? Do you not like
this? Please let me know down in the comments or on the repository for
the .NET MAUI Community Toolkit. We can improve and make
things better for you otherwise. Until then, please click the like
button on this video so all the people can learn about the amazing FileSaver
that we have right here. I would very much appreciate that subscribe to my
channel if you haven't picked up on the hints in this video earlier. And before you go,
maybe you want to also pick a folder which is also
something amazing that's in the .NET MAUI Community Toolkit. Check
the video for that right here. Or check out this full playlist with amazing
.NET MAUI Community Toolkit videos on this side and I'll be seeing you
for the next video.