UWP应用读写本地JSON文件遇System.IO.FileLoadException进程占用错误
解决本地JSON文件读写时的文件占用异常(System.IO.FileLoadException)
嘿,这个问题我日常开发中碰到好多次了!你遇到的System.IO.FileLoadException本质上就是文件被未释放的资源占用,或者多个操作同时读写同一文件导致的。下面给你几个实用的解决方案,按优先级排序:
1. 用using语句确保文件流自动释放
这是最基础也最关键的一步。很多时候我们手动打开了文件流(比如StreamReader/StreamWriter/FileStream),但忘记关闭,导致文件一直被锁定。而using语句会在代码块结束后自动调用Dispose()方法,不管有没有异常,都会释放文件资源。
举个读写JSON的示例:
// 读取JSON数据 public YourDataModel LoadAppData() { const string filePath = "appData.json"; if (!File.Exists(filePath)) return new YourDataModel(); // 返回默认初始数据 using var reader = new StreamReader(filePath); var jsonContent = reader.ReadToEnd(); return JsonSerializer.Deserialize<YourDataModel>(jsonContent); } // 写入JSON数据 public void SaveAppData(YourDataModel data) { const string filePath = "appData.json"; var jsonContent = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); using var writer = new StreamWriter(filePath); writer.Write(jsonContent); }
如果你嫌手动处理流麻烦,也可以直接用File类的静态方法(比如File.ReadAllText/File.WriteAllText),这些方法内部已经封装了using逻辑,会自动处理文件流的打开和关闭:
// 更简洁的读取方式 var json = File.ReadAllText("appData.json"); // 更简洁的写入方式 File.WriteAllText("appData.json", jsonContent);
2. 加锁避免并发读写冲突
如果你的应用是多线程场景,或者在多个地方同时触发读写操作,就会出现“同一时间多个进程/线程抢文件”的情况。这时候需要用lock语句来保证同一时间只有一个操作能访问文件。
示例代码:
// 定义一个全局锁对象(必须是static的,确保所有操作共用同一锁) private static readonly object _fileLock = new object(); public YourDataModel LoadAppData() { lock (_fileLock) // 加锁,确保读取时没有写入操作 { const string filePath = "appData.json"; if (!File.Exists(filePath)) return new YourDataModel(); var jsonContent = File.ReadAllText(filePath); return JsonSerializer.Deserialize<YourDataModel>(jsonContent); } } public void SaveAppData(YourDataModel data) { lock (_fileLock) // 加锁,确保写入时没有读取操作 { const string filePath = "appData.json"; var jsonContent = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(filePath, jsonContent); } }
3. 添加重试机制处理临时占用
有时候文件可能被外部程序临时占用(比如用户用记事本打开了JSON文件),这时候可以加个重试逻辑,尝试几次后再抛出异常,提升用户体验:
public string ReadFileWithRetry(string filePath, int maxRetries = 3, int delayMs = 200) { for (int retry = 0; retry < maxRetries; retry++) { try { return File.ReadAllText(filePath); } catch (IOException) when (retry < maxRetries - 1) // 只在重试次数没到的时候捕获异常 { Thread.Sleep(delayMs); } } throw new IOException($"无法读取文件 {filePath},已尝试{maxRetries}次,文件可能被其他进程占用"); }
4. 检查代码中是否有遗漏的流资源
如果上面的方法都没用,那你得仔细排查代码:有没有手动打开FileStream后没关闭?有没有用第三方库读写文件但没释放资源?比如下面这种错误写法一定要避免:
// ❌ 错误示例:没关闭流,导致文件一直被锁定 var stream = new FileStream("appData.json", FileMode.Open); var reader = new StreamReader(stream); var json = reader.ReadToEnd(); // 忘记调用 stream.Close() 或 reader.Dispose()
这种情况要么用using包裹,要么在finally块里手动关闭流。
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

