Xamarin开发中UWP/Android删除文件报UnauthorizedAccessException如何解决?
Xamarin跨平台文件操作无权限异常解决方案
问题根因
你遇到的System.UnauthorizedAccessException和沙箱机制没有直接关联,核心原因是文件占用导致的访问拒绝:
你使用ImageSource.FromFile()加载本地磁盘文件时,Xamarin.Forms对应平台的渲染器会对该文件加持久化只读锁,你后续调用File.Delete()时,因为文件被框架持有锁无法操作,才会抛出无权限异常。UWP端可以写入但无法删除的表现也完全符合文件占用的特征,写入操作完成后你主动释放了FileStream,但图片加载的锁会一直持有到图片引用被释放为止。
修复方案
- 替换图片加载方式,避免锁磁盘文件
你代码中写入文件时已经拿到了完整的文件字节数组bArray,直接用内存流生成图片源即可,完全不需要读取磁盘文件,修改对应代码:
// 替换原来的 CreatedImage = ImageSource.FromFile(filepath); CreatedImage = ImageSource.FromStream(() => new MemoryStream(bArray));
该方案生成的图片源完全基于内存数据,不会对磁盘上的源文件加任何锁,删除操作不会再被拦截。
- 优化删除逻辑的鲁棒性
如果业务必须使用ImageSource.FromFile()加载,删除前先主动解除图片对文件的引用:
public void DeleteFiles() { // 先解除图片对文件的引用 CreatedImage = null; // 强制触发GC回收释放文件锁 GC.Collect(); GC.WaitForPendingFinalizers(); if (!Directory.Exists(fileFolder)) return; string[] filePaths = Directory.GetFiles(fileFolder); foreach(string filePath in filePaths) { try { if (File.Exists(filePath)) File.Delete(filePath); } catch (IOException) { // 可根据业务需求增加3-5次的延迟重试逻辑 } } }
权限配置修正
- Android端:Android 13(API 33)及以上版本,原有
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限已废弃,需根据访问的文件类型配置对应权限:访问图片配置READ_MEDIA_IMAGES,音频配置READ_MEDIA_AUDIO,视频配置READ_MEDIA_VIDEO。 - UWP端:
Environment.SpecialFolder.LocalApplicationData对应应用沙箱内的LocalState目录,默认拥有完整读写删权限,无需额外配置broadFileAccess权限,该权限仅用于访问沙箱外的系统目录,非必要配置可能影响应用商店审核。
- Android端:Android 13(API 33)及以上版本,原有
补充空引用防护
你当前代码中FilePicker.PickMultipleAsync返回结果为null时(用户主动取消选择)直接调用ToList()会触发空引用异常,需增加空判断:
IEnumerable<FileResult> pickedFiles = await FilePicker.PickMultipleAsync(pickOptions); if (pickedFiles == null) return; List<FileResult> results = pickedFiles.ToList();
关于文件夹选择器的补充
如果需要实现文件夹选择功能,可通过依赖服务分别调用各平台原生能力实现:UWP端调用Windows.Storage.Pickers.FolderPicker,Android端调用Intent.ACTION_OPEN_DOCUMENT_TREE,iOS端调用UIDocumentPickerViewController指定文档类型为文件夹即可,不需要自行实现文件扫描逻辑,也能完全避开沙箱权限限制。
内容的提问来源于stack exchange,提问作者Florian Pfützenreuter
相关产品推荐
相关产品推荐

