【问题标题】:Write a collection of strings to a file using .NET Maui使用 .NET Maui 将字符串集合写入文件
【发布时间】:2022-11-09 15:28:26
【问题描述】:

在标准的 Windows 程序中,我将使用以下内容将字符串集合写入文件......

public static async Task ExampleAsync()
{
    string[] lines =
    {
        "First line", "Second line", "Third line" 
    };

    await File.WriteAllLinesAsync("WriteLines.txt", lines);
}

如何在 .NET Maui 应用程序中做同样的事情?我试过了...

 await streamWriter.WriteAsync(lines);

【问题讨论】:

  • StreamWriter/TextWriter 没有将字符串集合写入行的方法。但它有用于编写的方法(及其异步对应物)一个线,写线/异步.所以基本上,循环你的字符串集合/数组并用写线/异步.但是,您为什么不使用 System.IO.File.WriteAllLinesAsync?毕竟,在您的相关问题中,您在 MAUI 应用程序中使用 System.IO.File.OpenWrite 没有任何问题...

标签: c# .net-maui


【解决方案1】:
- AppShell.xaml :
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="TP1.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:view="clr-namespace:TP1.Views"
Shell.FlyoutBehavior="Disabled">
<!--<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />-->
<TabBar>
<!--<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate view:Note}"
Icon="icon_notes" />-->
<ShellContent Title="Liste Notes"
ContentTemplate="{DataTemplate view:ListeNotes}"
Icon="icon_notes" />
<ShellContent
Title="A Propos"
ContentTemplate="{DataTemplate view:APropos}"
Icon="icon_about" />
</TabBar>
</Shell>
- Note.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TP1.Views.Note"
Title="Note">
<VerticalStackLayout Spacing="10" Margin="5">
<Editor x:Name="TextEditor"
Placeholder="Taper votre note"
HeightRequest="100"
Text="{Binding Text}" />
<Grid ColumnDefinitions="*,*" ColumnSpacing="4">
<Button Text="Enregistrer"
Clicked="ButtonEnregistrer_Clicked" />
<Button Grid.Column="1"
Text="Supprimer"
Clicked="ButtonSupprimer_Clicked" />
</Grid>
</VerticalStackLayout>
TP .Net Maui n° 1 (Suite) : Application à notes multiples
2
</ContentPage>
- Note.xaml.cs
namespace TP1.Views;
[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class Note : ContentPage
{
string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
public string ItemId
{
set { ChargerNote(value); }
}
public Note()
{
InitializeComponent();
//if (File.Exists(_fileName))
// TextEditor.Text = File.ReadAllText(_fileName);
string appDataPath = FileSystem.AppDataDirectory;
//string sFileName = "notes.txt";
//ChargerNote(Path.Combine(appDataPath, sFileName));
string sFileName = $"{Path.GetRandomFileName()}.notes.txt";
ChargerNote(Path.Combine(appDataPath, sFileName));
}
private void ChargerNote(string fileName)
{
Models.CNote noteModel = new Models.CNote();
noteModel.Filename = fileName;
if (File.Exists(fileName))
{
noteModel.Date = File.GetCreationTime(fileName);
noteModel.Text = File.ReadAllText(fileName);
}
BindingContext = noteModel;
}
private async void ButtonEnregistrer_Clicked(object sender, EventArgs e)
{
//File.WriteAllText(_fileName, TextEditor.Text);
if (BindingContext is Models.CNote note)
File.WriteAllText(note.Filename, TextEditor.Text);
await Shell.Current.GoToAsync("..");
}
private async void ButtonSupprimer_Clicked(object sender, EventArgs e)
{
//if (File.Exists(_fileName))
// File.Delete(_fileName);
//TextEditor.Text = string.Empty;
if (BindingContext is Models.CNote note)
{
if (File.Exists(note.Filename))
File.Delete(note.Filename);
}
await Shell.Current.GoToAsync("..");
}
}
- APropos.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TP1.Views.APropos"
xmlns:models="clr-namespace:TP1.Models"
Title="APropos">
<!-- BindingContext => Liaison entre la vue (cette page) et le model (classe CApropos) -->
<ContentPage.BindingContext>
<models:CApropos />
</ContentPage.BindingContext>
<VerticalStackLayout Spacing="10" Margin="10">
<Image Source="logo_groupe3il.jpg"
SemanticProperties.Description="Cette application est une production 3iL"
HeightRequest="64" HorizontalOptions="CenterAndExpand"/>
<!--<Label FontSize="22" FontAttributes="Bold" Text="Notes 3iL" VerticalOptions="End"
TextColor="{StaticResource Secondary}"/>
<Label FontSize="22" Text="v1.0" VerticalOptions="End" TextColor="{StaticResource
Secondary}"/>
<Label Text="Application XAML/C# écrite en .NET MAUI."
TextColor="{StaticResource Primary}"/>-->
<Label FontSize="22" FontAttributes="Bold" Text="{Binding Title}" VerticalOptions="End"
TextColor="{StaticResource Secondary}"/>
<Label FontSize="22" Text="{Binding Version}" VerticalOptions="End"
TextColor="{StaticResource Secondary}"/>
<Label Text="{Binding Message}" TextColor="{StaticResource Primary}"/>
<Button Text="En savoir plus sur 3iL" Clicked="APropos_Clicked" />
</VerticalStackLayout>
</ContentPage>
- APropos.xaml.cs
namespace TP1.Views;
public partial class APropos : ContentPage
{
public APropos()
{
InitializeComponent();
}
private async void APropos_Clicked(object sender, EventArgs e)
{
if (BindingContext is Models.CApropos apropos)
{
await Launcher.Default.OpenAsync(apropos.MoreInfoUrl);
}
//await Launcher.Default.OpenAsync("https://www.3il-ingenieurs.fr/");
}
}
- CPropos.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TP1.Models
{
internal class CApropos
{
public string Title => "Notes 3iL - " + AppInfo.Name;
public string Version => AppInfo.VersionString;
public string MoreInfoUrl => "https://www.3il-ingenieurs.fr/";
public string Message => "Application XAML/C# écrite en .NET MAUI.";
4
}
}
- Note.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TP1.Views.Note"
Title="Note">
<VerticalStackLayout Spacing="10" Margin="5">
<Editor x:Name="TextEditor"
Placeholder="Taper votre note"
HeightRequest="100"
Text="{Binding Text}" />
<Grid ColumnDefinitions="*,*" ColumnSpacing="4">
<Button Text="Enregistrer"
Clicked="ButtonEnregistrer_Clicked" />
<Button Grid.Column="1"
Text="Supprimer"
Clicked="ButtonSupprimer_Clicked" />
</Grid>
</VerticalStackLayout>
</ContentPage>
- Note.xaml.cs
namespace TP1.Views;
[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class Note : ContentPage
{
string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
public string ItemId
{
set { ChargerNote(value); }
}
public Note()
{
InitializeComponent();
//if (File.Exists(_fileName))
// TextEditor.Text = File.ReadAllText(_fileName);
string appDataPath = FileSystem.AppDataDirectory;
//string sFileName = "notes.txt";
//ChargerNote(Path.Combine(appDataPath, sFileName));
string sFileName = $"{Path.GetRandomFileName()}.notes.txt";
ChargerNote(Path.Combine(appDataPath, sFileName));
}
private void ChargerNote(string fileName)
{
Models.CNote noteModel = new Models.CNote();
noteModel.Filename = fileName;
if (File.Exists(fileName))
{
noteModel.Date = File.GetCreationTime(fileName);
noteModel.Text = File.ReadAllText(fileName);
}
BindingContext = noteModel;
}
private async void ButtonEnregistrer_Clicked(object sender, EventArgs e)
5
{
//File.WriteAllText(_fileName, TextEditor.Text);
if (BindingContext is Models.CNote note)
File.WriteAllText(note.Filename, TextEditor.Text);
await Shell.Current.GoToAsync("..");
}
private async void ButtonSupprimer_Clicked(object sender, EventArgs e)
{
//if (File.Exists(_fileName))
// File.Delete(_fileName);
//TextEditor.Text = string.Empty;
if (BindingContext is Models.CNote note)
{
if (File.Exists(note.Filename))
File.Delete(note.Filename);
}
await Shell.Current.GoToAsync("..");
}
}
- CNote.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TP1.Models
{
internal class CListeNotes
{
public ObservableCollection<CNote> CollNotes { get; set; } = new
ObservableCollection<CNote>();
public CListeNotes() => ChargerNotes();
public void ChargerNotes()
{
CollNotes.Clear();
string appDataPath = FileSystem.AppDataDirectory;
IEnumerable<CNote> listenotes = Directory.EnumerateFiles(appDataPath, "*.notes.txt")
.Select(filename => new CNote()
{
Filename = filename,
Text = File.ReadAllText(filename),
Date = File.GetCreationTime(filename)
})
.OrderBy(note => note.Date);
foreach (CNote note in listenotes)
CollNotes.Add(note);
}
}
}
- ListeNotes.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TP1.Views.ListeNotes"
Title="Liste Notes">
<!--<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI!"
6
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>-->
<ContentPage.ToolbarItems>
<ToolbarItem Text="Ajouter" Clicked="Ajouter_Clicked" IconImageSource="{FontImage
Glyph='+', Color=White, Size=22}" />
</ContentPage.ToolbarItems>
<CollectionView x:Name="CollectionDeNotes"
ItemsSource="{Binding CollNotes}"
Margin="20"
SelectionMode="Single"
SelectionChanged="CollectionDeNotes_SelectionChanged">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" ItemSpacing="10" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Text}" FontSize="22"/>
<Label Text="{Binding Date}" FontSize="14" TextColor="Silver"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
- ListeNotes.xaml.cs
//using static Android.Provider.ContactsContract.CommonDataKinds;
namespace TP1.Views;
public partial class ListeNotes : ContentPage
{
public ListeNotes()
{
InitializeComponent();
Routing.RegisterRoute($"{nameof(Note)}", typeof(Note));
BindingContext = new Models.CListeNotes();
}
protected override void OnAppearing()
{
((Models.CListeNotes)BindingContext).ChargerNotes();
}
private async void CollectionDeNotes_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
//await Shell.Current.GoToAsync(nameof(Note));
if (e.CurrentSelection.Count != 0)
{
var note = (Models.CNote)e.CurrentSelection[0];
await
Shell.Current.GoToAsync($"{nameof(Note)}?{nameof(Note.ItemId)}={note.Filename}");
CollectionDeNotes.SelectedItem = null;
}
}
private async void Ajouter_Clicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync(nameof(Note));
}
}
7
- CListeNotes.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TP1.Models
{
internal class CListeNotes
{
public ObservableCollection<CNote> CollNotes { get; set; } = new
ObservableCollection<CNote>();
public CListeNotes() => ChargerNotes();
public void ChargerNotes()
{
CollNotes.Clear();
string appDataPath = FileSystem.AppDataDirectory;
IEnumerable<CNote> listenotes = Directory.EnumerateFiles(appDataPath, "*.notes.txt")
.Select(filename => new CNote()
{
Filename = filename,
Text = File.ReadAllText(filename),
Date = File.GetCreationTime(filename)
})
.OrderBy(note => note.Date);
foreach (CNote note in listenotes)
CollNotes.Add(note);
}
}
}

【讨论】:

    【解决方案2】:

    此解决方案有效:

     string targetFileName = "Output1.txt";
    
            StringBuilder sb = new StringBuilder();
            sb.Append("Line 1");
            sb.Append("Line 2");
    
            // Write the file content to the app data directory
            string targetFile = System.IO.Path.Combine(FileSystem.Current.AppDataDirectory, targetFileName);
    
            using FileStream outputStream = System.IO.File.OpenWrite(targetFile);
            using StreamWriter streamWriter = new StreamWriter(outputStream);
    
            await streamWriter.WriteAsync(sb.ToString());
    

    【讨论】:

    • 关于这个问题,不,那是行不通的。在您的问题中,您演示了一个编写的代码多行到一个文件,你的问题询问如何在 MAUI 应用程序中实现相同的目标。但是您自己建议的解决方案仅写入包含文本“Line1Line2”的单行。如果您对此感到满意,那完全可以。但这不是您自己问题的正确答案。如果您使用 AppendLine 而不是 Append...
    猜你喜欢
    • 2011-10-24
    • 1970-01-01
    • 2012-05-14
    • 2019-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多