应用程序无法进一步处理 Xamarin 中的磁盘/文件夹
Posted
技术标签:
【中文标题】应用程序无法进一步处理 Xamarin 中的磁盘/文件夹【英文标题】:App cannot further process disks / folder in Xamarin 【发布时间】: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。这使得该文件仍在使用中。请尝试致电Flush
Dispose
@NicoZhu-MSFT 我尝试了您的 Flush and Dispose 方法。遗憾的是,这并没有成功。 using 不能确保 using-block 中所有使用过的资源都被释放?
@NicoZhu-MSFT 非常感谢你:)
【参考方案1】:
应用无法进一步处理 Xamarin 中的磁盘/文件夹
我用你的代码测试过,如果我们禁用CreatedImage = ImageSource.FromFile(filepath);
这一行,问题是当你删除文件时,图像控制正在使用该文件。它会按预期工作。
我需要那个图像控件来显示图像
我们建议您使用流渲染图像,但不要直接从文件创建源。
例如
CreatedImage = ImageSource.FromStream(() => stream);
【讨论】:
流必须是 MemoryStream 类型,普通流是不行的以上是关于应用程序无法进一步处理 Xamarin 中的磁盘/文件夹的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms 无法更改本地设备上 Xamarin.iOS 中的应用程序图标
无法使用 Xamarin.Android 中的 Xamarin.Mobile 组件保存联系人
Andrioid FileProvider在Xamarin.Forms中的使用