C# MAUI文件系统访问 C#在MAUI中如何读取应用沙箱或用户文件

1次阅读

maui中读取应用沙箱最安全方式是使用Filesystem.appdataDirectory配合path.combine构造路径,并确保先创建目录、异步读取、避免遍历;资源文件须用openapppackagefileasync流式访问,共享目录需通过documentpicker合规获取。

C# MAUI文件系统访问 C#在MAUI中如何读取应用沙箱或用户文件

MAUI 中读取应用沙箱(LocalFolder)最安全的方式

MAUI 的 FileSystem.AppDataDirectory 是默认且唯一推荐的持久化存储位置,它对应各平台的沙箱私有目录(如 iosApplication SupportandroidgetFilesDir()windowsAppDataLocalPackages...LocalState)。这个路径无需额外权限,所有读写都天然受系统保护。

  • 直接用 Path.Combine(FileSystem.AppDataDirectory, "config.json") 构造路径,别拼字符串斜杠
  • 写文件前务必先 Directory.CreateDirectory(Path.GetDirectoryName(filePath))
  • 读取时用 File.ReadAllTextAsync(filePath),避免阻塞 UI 线程
  • 不要尝试把 AppDataDirectory 当成“根目录”去遍历——它不支持 Directory.EnumerateFiles 递归扫描(某些平台会抛 UnauthorizedAccessException

访问用户文档/下载等共享目录需运行时权限 + 平台特异性处理

FileSystem.OpenDocumentPickerAsync()FileSystem.SaveDocumentPickerAsync() 是跨平台唯一合规方式,适用于让用户主动选择文件。直接硬编码访问 Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) 在 iOS/macos 上无效,在 Android 上需要 READ_EXTERNAL_STORAGE(API 33+ 已弃用),在 Windows 上虽能返回路径但可能被 UAC 或 onedrive 重定向。

  • Android:必须在 AndroidManifest.xml 声明 android:requestLegacyExternalStorage="true"(仅限 targetSdk GetExternalStoragePublicDirectory 返回空
  • iOS:完全禁止直接访问 Documents 文件夹,只能通过 UIDocumentPickerViewController(即 MAUI 封装OpenDocumentPickerAsync
  • Windows:KnownFolders.DocumentsLibrary 需在 Package.appxmanifest 中声明 capabilities,且用户必须授予权限(首次调用会弹窗)

读取 Assets 资源文件要用 FileSystem.OpenAppPackageFileAsync

放在 ResourcesRaw 下的文件(如 ResourcesRawdefault.json)不是普通磁盘文件,不能用 File.ReadAllText 直接读。MAUI 把它们打包进应用包体,需通过流式打开:

  • 调用 await FileSystem.OpenAppPackageFileAsync("default.json") 返回 Stream
  • 必须用 using var stream = ... 确保及时释放,否则后续重复调用可能卡死或返回 NULL
  • 该方法不支持子目录嵌套(如 "data/config.json" 会失败),资源名必须与 ResourcesRaw 下的文件名完全一致(区分大小写)
  • 如果是图片或二进制资源,别用 StreamReader,直接 stream.CopyToAsync(destStream)

调试时路径看不见?用 Debugger.break() + 输出日志确认真实路径

FileSystem.AppDataDirectory 在不同设备上路径差异极大,模拟器和真机也不同。光靠文档推测容易出错。

  • 在读写前加 console.WriteLine($"AppData: {FileSystem.AppDataDirectory}");
  • Android 上可搭配 adb shell run-as your.package.id ls -l files/ 查看实际内容
  • iOS 上无法命令行访问,但可在断点处用 NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User)[0] 对比验证
  • Windows 上注意路径中含大段哈希串,不要手动复制粘贴,始终用变量传递

沙箱路径本身不难获取,真正容易翻车的是「以为路径存在就一定能读写」——每个平台对子目录创建、文件锁、编码格式、甚至隐藏文件(如 .DS_Store)的处理都不同。动手前先用最小路径写个空文件再读出来,比查十篇文档更可靠。

text=ZqhQzanResources