如何在 Xamarin UWP 应用程序中保存 csv 或 txt?

How to save a csv or txt in Xamarin UWP app?

今天我有一个关于在 UWP 平台上的 Xamarin 应用程序中保存 .csv 或 .txt 文件的问题。我正在尝试保存我在代码调用 tags.csv 中创建的文件。我的目标是最初不保存任何 .csv,我在我的代码中创建一个实例,然后保存它并在我的代码执行时创建一个新的 .csv 文件。 .csv 的创建和填充发生在一个函数中,该函数基于我的应用程序中的 Button 实例触发。另外,理想情况下,我可以将其保存在由文件资源管理器弹出窗口确定的位置。

到目前为止,我已经尝试了两种方法来制作和保存 .csv 文件,CSVExport package and CSVhelper package。我已经能够成功地从 NuGet 下载并添加到我的项目中。

我分别尝试了每个的简单实现,基本上只是使用他们的示例代码来查看它是否适用于我的 UWP 应用程序。这是相应的代码

// CSVExport methods, two ways to save
var myExport = new CsvExport();
...
File(myExport.ExportToBytes(), "text/csv", "results.csv"); // method 1
myExport.ExportToFile("./results.csv");                    // method 2

// CSVhelper method
var records = new List<Foo>
{
   new Foo { Id = 1, Name = "one" },
};                
using (var writer = new StreamWriter("./tags.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
   csv.WriteRecords(records);
}

这是我收到的错误: System.UnauthorizedAccessException:'Access to the path C:...(filepath)...BLE.Client.UWP\bin\x86\Debug\AppX\tags.csv' 被拒绝。'

每当代码到达我保存的 .csv 文件时,应用程序就会崩溃,Visual Studio 2022 会给我这个错误消息。无论我使用 CSVExport 还是 CSVhelper,都会出现同样的错误。

尝试的解决方案:

我尝试的解决方案主要是关于为应用程序提供它需要保存的权限。如果像获取不同的 CSV 包这样的替代方案更好,我也会接受这个建议。

我在 Whosebug 上看到的一个解决方案 linked to this page. 问题是我无法在我的 Xamarin 应用程序中加载 StorageFolder 或 Windows.Storage,它无法识别它并且无法编译,因为它丢失了加载操作。

我看到的另一个解决方案是在 Package.appxmanifest 文件中更改您的功能并更改您的包 header。我已经这样做了,所以我的看起来像下面的代码示例。我需要 internetClient 和蓝牙以及应用程序本身的位置,所以我添加了 broadFilesystemaccess 甚至文档和图片只是为了看看它是否也能工作。

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp rescap">

 ...

<Capabilities>
  <Capability Name="internetClient" />
  <rescap:Capability Name="broadFileSystemAccess" />

  <uap:Capability Name="documentsLibrary"/>
  <uap:Capability Name="picturesLibrary" />

  <DeviceCapability Name="bluetooth" />
  <DeviceCapability Name="location"/>  
</Capabilities>

另一个解决方案是确保 UWP 应用程序具有权限,我进入系统设置并允许,因此它现在应该具有完全访问权限。

我不确定从这里去哪里,所以任何关于 UWP 或在 Xamarin UWP 应用程序中保存文件的建议都将不胜感激。

根据您的要求,您可以尝试使用 Xamarin.Forms 的 DependencyService 功能。

DependencyService 使您能够从共享代码调用本机平台功能。对于您的场景,您可以先将文件流传递给 DependencyService 。那么您可以在表单应用程序中使用 DependencyService 调用 UWP FileSavePicker 并将流保存为文件。

这里有一些关于如何实现接口的代码片段。

SaveFileAsync

        public async Task SaveFileAsync(Stream data)
    {
        FileSavePicker savePicker = new FileSavePicker();
        savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        // Dropdown of file types the user can save the file as
        savePicker.FileTypeChoices.Add("Text", new List<string>() { ".txt" });
        savePicker.FileTypeChoices.Add("CSV", new List<string>() { ".csv" });
        // Default file name if the user does not type one in or select a file to replace
        savePicker.SuggestedFileName = "New Document";

        StorageFile file = await savePicker.PickSaveFileAsync();
       
        if (file!= null) 
        {
            using (IRandomAccessStream dataStream= data.AsRandomAccessStream()) 
            {
                using (var reader = new DataReader(dataStream.GetInputStreamAt(0)))
                {
                    await reader.LoadAsync((uint)dataStream.Size);
                    var buffer = new byte[(int)dataStream.Size];
                    reader.ReadBytes(buffer);
                    await Windows.Storage.FileIO.WriteBytesAsync(file, buffer);
                }
            }
        }
    }

ISaveFileServicecs 接口

 public interface ISaveFileServicecs
    {
        Task<Stream> SaveFileAsync(Stream stream);
    }

用法

 await DependencyService.Get<ISaveFileServicecs>().SaveFileAsync(stream);