【发布时间】:2021-11-09 08:58:29
【问题描述】:
嘿,我是 Xamarin 的新手,希望你们能帮助我。由于 xamarin 中没有默认的文件夹选择器,我想自己实现它。问题是 UWP 和 Android 向我抛出了这个异常:
System.UnauthorizedAccessException H结果=0x80070005 Nachricht = 拒绝访问路径“C:\Users\imtt\AppData\Local\Packages\3ef1aa30-7ffe-4ece-84c7-d2eaf1f8634b_wvdsmkc2tee92\LocalState\Test\199.jpg”。 Quelle = System.IO.FileSystem Stapelüberwachung: 北 System.IO.FileSystem.DeleteFile(String fullPath) bei System.IO.File.Delete(字符串路径) 在 C:\Users\imtt\source\repos\MinimalReproducibleExample\MinimalReproducibleExample\MinimalReproducibleExample\ViewModel.cs 中的 BEI MinimalReproducibleExample.ViewModel.DeleteFiles():Zeile107 北 Xamarin.Forms.Command.c__DisplayClass4_0.<.ctor>b__0(Object o) 北 Xamarin.Forms.Command.Execute(对象参数) 北 Xamarin.Forms.ButtonElement.ElementClicked(VisualElement visualElement, IButtonElement ButtonElementManager) 北 Xamarin.Forms.Button.SendClicked() bei Xamarin.Forms.Platform.UWP.ButtonRenderer.OnButtonClick(Object sender, RoutedEventArgs e)
这是 xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MinimalReproducibleExample.MainPage">
<StackLayout>
<Button Text="Add Image" Command="{Binding AddImage}"/>
<Button Text="Delete Images" Command="{Binding DeleteImages}"/>
<Image Source="{Binding CreatedImage}"/>
</StackLayout>
这是代码隐藏:
using Xamarin.Forms;
namespace MinimalReproducibleExample
{
public partial class MainPage : ContentPage
{
public MainPage()
{
BindingContext = new ViewModel();
InitializeComponent();
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MinimalReproducibleExample
{
public class ViewModel : INotifyPropertyChanged
{
private ImageSource image;
private string fileFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Test");
public ICommand AddImage { get; }
public ICommand DeleteImages { get; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public ViewModel()
{
AddImage = new Command(ShowFilePicker);
DeleteImages = new Command(DeleteFiles);
}
public ImageSource CreatedImage
{
get => image;
set
{
image = value;
OnPropertyChanged();
}
}
public async void ShowFilePicker()
{
FilePickerFileType filePickerFileType = new FilePickerFileType(
new Dictionary<DevicePlatform, IEnumerable<string>> {
{ DevicePlatform.iOS, new [] { "jpeg", "png", "mp3", "mpeg4Movie", "plaintext", "utf8PlainText", "html" } },
{ DevicePlatform.Android, new [] { "image/jpeg", "image/png", "audio/mp3", "audio/mpeg", "video/mp4", "text/*", "text/html" } },
{ DevicePlatform.UWP, new []{ "*.jpg", "*.jpeg", "*.png", "*.mp3", "*.mp4", "*.txt", "*.html" } }
});
PickOptions pickOptions = new PickOptions
{
PickerTitle = "Wählen Sie eine oder mehrere Dateien aus",
FileTypes = filePickerFileType,
};
IEnumerable<FileResult> pickedFiles = await FilePicker.PickMultipleAsync(pickOptions);
List<FileResult> results = pickedFiles.ToList();
if (results != null && results.Count > 0)
{
foreach (FileResult fileResult in results)
{
using (Stream stream = await fileResult.OpenReadAsync())
{
DirectoryInfo directoryInfo = Directory.CreateDirectory(fileFolder);
string directoryPath = directoryInfo.FullName;
string filepath = Path.Combine(directoryPath, fileResult.FileName);
try
{
byte[] bArray = new byte[stream.Length];
using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate))
{
stream.Read(bArray, 0, (int)stream.Length);
int length = bArray.Length;
fs.Write(bArray, 0, length);
}
CreatedImage = ImageSource.FromFile(filepath);
}
catch (Exception exc)
{
}
}
}
}
}
public void DeleteFiles()
{
string[] filePaths = Directory.GetFiles(fileFolder);
foreach(string filePath in filePaths)
{
File.Delete(filePath);
}
}
}
}
我已经通过 Windows 设置为我的应用授予了对文件系统的访问权限,还授予了 Android 部分的读写权限。我什至给了 UWP 部分的“broadFileAccess”,即使这样也没有成功。
这与另一个问题相交,UWP部分可以将文件写入“Environment.SpecialFolder.LocalApplicationData”中的文件夹,但不允许删除该文件夹中的文件。
这和 UWP 和 Android 的沙盒有关系吗?
【问题讨论】:
-
Environment.SpecialFolder.LocalApplicationData 匹配的文件夹是UWP平台的本地存储。并且拥有完全权限,可以读写文件。
-
@NicoZhu-MSFT 感谢您的回复,我添加了代码 sn-ps 用于文件创建和删除。
-
我认为不允许您删除文件的原因是您没有在写入后刷新和处置FileStream。这使得该文件仍在使用中。请尝试致电
FlushDispose -
@NicoZhu-MSFT 我尝试了您的 Flush and Dispose 方法。遗憾的是,这并没有成功。 using 不能确保 using-block 中所有使用过的资源都被释放?
-
@NicoZhu-MSFT 非常感谢你:)
标签: android ios xamarin uwp file-handling