如何在 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);
今天我有一个关于在 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);