UWP:文件修改时RandomAccessStream读取中断问题求助
解决持续新增内容的文件读取问题(文件修改时InputStream失效的问题)
我明白你现在的困扰:用StreamReader读取不断新增内容的文件时,只要文件被修改,原来的InputStream就会变成0,导致读取循环直接终止。这种情况在监控日志文件或者实时生成的文本文件时很常见,给你几个实用的解决方案:
方案1:文件系统监控+增量读取(推荐)
核心思路是用FileSystemWatcher监控文件的写入变化,每次检测到更新时,重新打开文件并从上次读取的位置开始读取新增内容。这种方式效率高,能精准响应文件变化。
private long _lastReadPosition = 0; private readonly string _filePath = "替换为你的文件路径"; public async Task StartMonitoringFile() { // 创建文件监控器,监听目标文件的写入变化 var watcher = new FileSystemWatcher(Path.GetDirectoryName(_filePath), Path.GetFileName(_filePath)); watcher.NotifyFilter = NotifyFilters.LastWrite; watcher.Changed += async (sender, e) => await ReadNewContentAsync(); watcher.EnableRaisingEvents = true; // 先读取文件初始内容 await ReadNewContentAsync(); } private async Task ReadNewContentAsync() { try { // 用FileShare.ReadWrite打开,允许其他进程同时写入文件 using (var fileStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { // 跳转到上次读取结束的位置 fileStream.Seek(_lastReadPosition, SeekOrigin.Begin); using (var streamReader = new StreamReader(fileStream)) { string line; while ((line = await streamReader.ReadLineAsync()) != null) { // 这里处理每一行新增的内容 Console.WriteLine(line); } // 更新读取位置,下次从这里开始 _lastReadPosition = fileStream.Position; } } } catch (IOException) { // 遇到文件被临时锁定的情况,稍等后重试 await Task.Delay(100); await ReadNewContentAsync(); } }
方案2:循环重试+持续检查(简单直接)
如果不想用监控器,也可以用循环持续检查文件,当读取流失效时,重新打开文件并从上次位置继续读取。这种方式实现简单,但会有一定的轮询开销。
private long _lastReadPos = 0; private readonly string _targetFile = "替换为你的文件路径"; public async Task ReadFileContinuously() { while (true) { try { using (var fileStream = new FileStream(_targetFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { fileStream.Seek(_lastReadPos, SeekOrigin.Begin); using (var reader = new StreamReader(fileStream)) { string line; while ((line = await reader.ReadLineAsync()) != null) { // 处理新增内容 Console.WriteLine(line); _lastReadPos = fileStream.Position; } } } // 没有新内容时,短暂等待后再检查 await Task.Delay(500); } catch (Exception ex) { // 处理异常(比如文件被删除、权限不足等) Console.WriteLine($"读取出错: {ex.Message}"); await Task.Delay(1000); } } }
几个关键注意事项
- 必须使用
FileShare.ReadWrite:如果不设置这个参数,当其他进程写入文件时,你的读取操作会被阻塞或者抛出异常。 - 记录读取位置:这是实现增量读取的核心,避免每次都从头读取整个文件,重复处理旧内容。
- 异常处理:文件操作很容易遇到临时锁定、文件丢失等情况,一定要加重试或异常处理逻辑,保证程序稳定性。
- 另外提一句:你原来的代码里,
using语句会自动帮你调用Close和Dispose,所以手动写streamReader.Close(); inputStream.Dispose();是多余的哦。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

