Working with files in .NET MAUI
Tags: csharp, dotnet, maui, ios
Published: 2023-06-15 15:55:25

In this article, I would like to talk about files on mobile devices. We'll create files, open them in a file explorer, and filter by type. Let's go.

Above all, let's create a simple MAUI project:

```csharp
dotnet new maui -n FilePickAndSaveSample
```

Let's go to the "MainPage.xaml” file and delete all elements in VerticalStackLayout block. It's no need us. In "MainePage.xaml.cs” file, the same delete redutant code and leave only constructor.
Following step, you need to install the "CommunityToolkit.Maui” package. After you'll do it, you should register it. For this go to the "MauiProgram.cs” and add this code:

```csharp
var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .UseMauiCommunityToolkit()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });
```

Next, let's make saving files to our mobile device.  Lets back to our "MainPage.xaml” file and add a couple items: button and label.

```xaml
<Label
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    LineBreakMode="WordWrap"
    Text="The FileSaver provides the ability to select target     folder and save files to the file system." />

<Button
    Clicked="SaveFile_Clicked"
    HorizontalOptions="Center"
    Text="Save file" />
```

And then go to the "MainPage.xaml.cs” file and create two handlers:

```csharp
private async void SaveFile_Clicked(object sender, EventArgs e)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        CancellationToken cancellationToken = cancellationTokenSource.Token;
        
        try
        {
            await SaveFile(cancellationToken);
        }
        catch (OperationCanceledException)
        {
            throw new OperationCanceledException("It was cancelled");
        }
    }
```

And also let's create a separate method for save files:

```csharp
private async Task SaveFile(CancellationToken cancellationToken)
    {
        using var stream = new MemoryStream(Encoding.Default.GetBytes("Hello from the Dev.to Community!"));
        var fileName = Application.Current?.MainPage?.DisplayPromptAsync("FileSaver", "Choose filename") ?? Task.FromResult("untitled.txt");
        var fileSaverResult = await FileSaver.Default.SaveAsync(await fileName, stream, cancellationToken);
        if (fileSaverResult.IsSuccessful)
        {
            await Toast.Make($"The file was saved successfully to location: {fileSaverResult.FilePath}").Show(cancellationToken);
        }
        else
        {
            await Toast.Make($"The file was not saved successfully with error: {fileSaverResult.Exception.Message}").Show(cancellationToken);
        }
    }
```

But it's not all. Let's go back to the "MauiProgram.cs” file and register service, just add this row:

```csharp
builder.Services.AddSingleton(FileSaver.Default);
```

By the way. How you might have noticed we injected service FileSaver statical way, but you can use another two ways: inject to constructor or create new instance. For convenient, I'll use static injecting.

But anyway let's check out.

![Stage 1: main](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2hxlra5e0tbpd99c8ag.png)

Click to the "Save TXT” button:


![Stage 1: type name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xgj6bndz2c5fn0iscmoj.png)

Type "plain_text.txt” and tap OK. Further, choose local storage and move into it. Repeat the same procedure for “doc_text.doc” and "pic.jpeg”

And now, lets create service for pick folder. It's everything similiar with save file. First, go to the "MauiProgram.cs” file and register new service:

```csharp
builder.Services.AddSingleton(FolderPicker.Default);
```

And also add lable and button:

```csharp
<Label
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    LineBreakMode="WordWrap"
    Text="FolderPicker allows you to pick a folder from the  device" />

<Button
    Clicked="PickFolder_Clicked"
    HorizontalOptions="Center"
    Text="Pick Folder" />
```

Also it needs handler and method:

```csharp
private async void PickFolder_Clicked(object sender, EventArgs e)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        CancellationToken cancellationToken = cancellationTokenSource.Token;
        
        try
        {
            await PickFolder(cancellationToken);
        }
        catch (OperationCanceledException)
        {
            throw new OperationCanceledException("It was cancelled");
        }
    }
    
    private async Task PickFolder(CancellationToken cancellationToken)
    {
        var folderResult = await FolderPicker.PickAsync("DCIM", cancellationToken);
        if (folderResult.IsSuccessful)
        {
            var filesCount = Directory.EnumerateFiles(folderResult.Folder.Path).Count();
            await Toast.Make($"Folder picked: Name - {folderResult.Folder.Name}, Path - {folderResult.Folder.Path}, Files count - {filesCount}", ToastDuration.Long).Show(cancellationToken);
        }
        else
        {
            await Toast.Make($"Folder is not picked, {folderResult.Exception.Message}").Show(cancellationToken);
        }
    }
```

Lets check out:

![Stage 2: main](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8swh4asixziefc1vig5d.png)

Click on the "Pick Folder” and select folder. If tap to button again, you'll be at the same folder that you selected earlier.

![Stage 2: selected folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xsm5iq9s39syjfs0lbkq.png)

And last thing that I wanted to show, it's pick file by type. Lets to do it and register service:

```csharp
builder.Services.AddSingleton(FilePicker.Default);
```

Add the lable and the couple of buttons:

```csharp
<Label
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    LineBreakMode="WordWrap"
    Text="FilePicker allows you to pick a file from the device" />

<Button
    Clicked="PickPhoto_Clicked"
    HorizontalOptions="Center"
    Text="Pick a Photo" />

<Button
    Clicked="PickFile_Clicked"
    HorizontalOptions="Center"
    Text="Pick a File" />

<Label
    FontSize="15"
    HorizontalTextAlignment="Center"
    x:Name="FileName" />
```

Add handlers:

```csharp
private async void PickPhoto_Clicked(object sender, EventArgs e)
    {
        FileResult result = await _filePicker.PickAsync(new PickOptions
        {
            PickerTitle = "Pick a Photo",
            FileTypes = FilePickerFileType.Images
        });

        if (result == null) return;

        FileName.Text = result.FileName;
    }

    private async void PickFile_Clicked(object sender, EventArgs e)
    {
        var customFileTypes = new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
        {
            {
                DevicePlatform.iOS, new[]
                {

                    "com.microsoft.word.doc",
                    "public.plain-text",
                    "org.openxmlformats.wordprocessingml.document"
                }
            },
            {
                DevicePlatform.Android, new[]
                {
                    "application/msword",
                    "text-plain",
                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                }
            },
            {
                DevicePlatform.WinUI, new[]
                {
                    "doc","docx", "txt"
                }
            },
        });

        FileResult result = await _filePicker.PickAsync(new PickOptions
        {
            PickerTitle = "Pick a File",
            FileTypes = customFileTypes
        });

        if (result == null) return;

        FileName.Text = result.FileName;
    }
```

And now we can check out. If you click "Pick a Photo”, you can choose only pictures.

![Stage 3: main](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i35y1a9lvtndpyptv58y.png)

![Stage 3: filtered file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ka6is521d2kdcqpxdxi6.png)

Thats all. Source: [CLICK](https://github.com/SergKorol/FilePickAndSaveSample)

Happy coding!

<a href="https://www.buymeacoffee.com/b9z99kntvtQ" target="_blank"><img src="http://dartfordwaffler.co.uk/wp-content/uploads/2021/03/buy-me-a-beer.jpg" alt="Buy Me A Beer" style="height: 60px !important;width: 317px !important;" ></a>