.NET MAUI Blazor访问RCL静态文件:Windows正常Android报错求助
跨平台不一致的原因及解决方法
核心原因
Windows和Android平台对RCL(Razor类库)中嵌入资源的打包/读取逻辑存在差异:
- Windows平台:当你将RCL的静态文件设置为「嵌入资源」+「始终复制」时,MAUI会将这些文件复制到主应用的输出目录中,形成真实的文件路径,因此
FileSystem.OpenAppPackageFileAsync能正常找到并读取文件。 - Android平台:APK打包时,标记为「嵌入资源」的文件会被直接嵌入到RCL的程序集(.dll)中,不会以独立物理文件的形式存在于APK的包目录里。
FileSystem.OpenAppPackageFileAsync是用于读取包内物理文件的API,自然找不到嵌入在程序集里的资源,因此抛出异常。
解决方法
根据你的需求(读取流/字节数组),有两种可靠的处理方式:
方式一:直接读取程序集嵌入资源(推荐,因为你已设置为嵌入资源)
既然文件已经是嵌入资源,直接从RCL的程序集中读取即可,跨平台通用:
- 确定嵌入资源的完整名称:默认命名规则为
[RCL项目命名空间].[目录层级].[文件名],例如你的RCL命名空间是BlazorAppCore,文件路径是wwwroot/sample-data/test.json,则资源名为BlazorAppCore.wwwroot.sample-data.test.json。 - 通过RCL中的任意类型获取其程序集,再读取资源流:
using System.Reflection; using System.IO; // 用RCL项目中的任意类来获取程序集(替换为你实际的类型) var rclAssembly = typeof(BlazorAppCore.YourRclClass).Assembly; // 替换为你的资源完整名称 var resourceFullName = "BlazorAppCore.wwwroot.sample-data.your-file-name.ext"; // 读取嵌入资源流 using var resourceStream = rclAssembly.GetManifestResourceStream(resourceFullName); if (resourceStream == null) { // 处理资源不存在的情况 throw new FileNotFoundException("指定的嵌入资源不存在", resourceFullName); } // 转换为字节数组(如果需要) using var memoryStream = new MemoryStream(); await resourceStream.CopyToAsync(memoryStream); byte[] fileBytes = memoryStream.ToArray();
- 验证资源名称:可以通过
rclAssembly.GetManifestResourceNames()方法列出该程序集所有嵌入资源,确认你要读取的资源名称是否正确。
方式二:调整文件属性,让Android将文件打包为物理文件
如果你坚持要用FileSystem.OpenAppPackageFileAsync读取,可修改RCL中静态文件的属性:
- 将「生成操作」从「嵌入资源」改为内容
- 保持「复制到输出目录」为「始终复制」
这样MAUI在打包Android APK时,会将这些文件复制到APK的assets/wwwroot/sample-data/目录下,此时FileSystem.OpenAppPackageFileAsync("wwwroot/sample-data/your-file-name.ext")就能在Windows和Android上正常工作。
内容的提问来源于stack exchange,提问作者slodki1997
相关产品推荐
相关产品推荐

