You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI调用OpenAppPackageFileAsync写入文件报流不可写异常咨询

异常原因

OpenAppPackageFileAsync 方法的设计用途仅为读取随应用安装包打包部署的内置资源,你存放在Resources\Raw下标记为MauiAsset的文件会被编译进各平台的应用安装包(Windows下为MSIX包、Android下为APK、iOS下为IPA),这类文件存储在系统级别的只读受保护目录中,应用本身对该路径没有写入权限,方法返回的流从设计上就是只读的,不存在可以开启写入权限的参数,直接往这个流写数据必然触发流不可写异常,这个行为在所有.NET MAUI支持的平台上都是一致的,不是Windows平台独有的问题。

正确实现方案

.NET MAUI跨平台本地文件读写的核心逻辑是:内置只读资源和运行时可写文件必须分开存储,操作步骤如下:

  • 所有运行时需要修改的文件,必须存放到系统分配给应用的可写私有目录下,通用可写路径通过FileSystem.Current.AppDataDirectory获取,该路径在全平台默认授予应用完整读写权限,不需要额外申请存储权限。
  • 如果你需要用Resources\Raw下的文件作为初始模板,在应用首次运行时将该只读资源拷贝到可写目录下,后续所有读写操作都针对可写目录中的拷贝文件执行,不要直接操作安装包内的原始资源。
  • 如果不需要初始模板,直接在可写目录下创建新文件即可。

代码示例

1. 首次启动初始化可写文件

仅在应用第一次启动、可写目录下不存在目标文件时,从安装包拷贝初始资源:

public async Task InitializeWritableCardFile()
{
    string writableFilePath = Path.Combine(FileSystem.Current.AppDataDirectory, "CardInfo.json");
    // 已存在则跳过初始化
    if (File.Exists(writableFilePath))
        return;
    
    // 从安装包只读资源拷贝初始模板
    using Stream sourceStream = await FileSystem.Current.OpenAppPackageFileAsync("CardInfo.json");
    using Stream targetStream = File.Create(writableFilePath);
    await sourceStream.CopyToAsync(targetStream);
}

2. 正确的文件写入方法

直接操作可写目录下的文件,不需要调用OpenAppPackageFileAsync:

public async Task WriteCardData(string data)
{
    string writableFilePath = Path.Combine(FileSystem.Current.AppDataDirectory, "CardInfo.json");
    // append参数传false为覆盖写入,传true为追加写入
    using StreamWriter writer = new StreamWriter(writableFilePath, append: false);
    await writer.WriteAsync(data);
}

3. 对应读取方法

public async Task<string> ReadCardData()
{
    string writableFilePath = Path.Combine(FileSystem.Current.AppDataDirectory, "CardInfo.json");
    if (!File.Exists(writableFilePath))
        return string.Empty;
    
    using StreamReader reader = new StreamReader(writableFilePath);
    return await reader.ReadToEndAsync();
}

补充说明

  • 严禁尝试修改安装包内的打包资源,所有平台都会对安装包做签名校验,强行写入不仅没有系统权限,还可能触发完整性校验导致应用崩溃。
  • 如果需要存储可被系统自动清理的临时缓存文件,可将路径替换为FileSystem.Current.CacheDirectory,该目录同样支持全平台直接读写。
  • Windows平台调试时如果想快速查看可写目录的文件位置,可以直接把AppDataDirectory返回的路径复制到资源管理器地址栏打开,就能看到你写入的CardInfo.json文件。

内容的提问来源于stack exchange,提问作者Benjamin Furlani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:15:35