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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:13:08