【问题标题】:Reading file content changes in .NET在 .NET 中读取文件内容更改
【发布时间】:2011-01-23 07:19:27
【问题描述】:

在 Linux 中,很多 IPC 是通过在一个进程中附加到文件并从另一个进程读取新内容来完成的。

我想在 Windows/.NET 中执行上述操作(使用管道等普通 IPC 太麻烦了)。我正在从 Python 进程附加到文件,并且我想在每次 FileSystemWatcher 报告事件时读取更改并且仅读取更改。我不想每次查找更改时都将整个文件内容读入内存(文件会很大)

每个追加操作都会追加一行数据,该行以唯一的递增计数器(时间戳+键)开始,以换行符结束。

【问题讨论】:

    标签: c# .net file ipc filesystemwatcher


    【解决方案1】:
        using (FileStream fs = new FileStream
           (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (StreamReader sr = new StreamReader(fs))
            {
                while (someCondition)
                {
                    while (!sr.EndOfStream)
                        ProcessLinr(sr.ReadLine());
                    while (sr.EndOfStream)
                        Thread.Sleep(100);
                    ProcessLinr(sr.ReadLine());            
                }
            }
        }
    

    这将帮助您只阅读附加的行

    【讨论】:

    • 一个伟大的解决方案,短而致命!
    【解决方案2】:

    您可以存储上次读取操作的偏移量,并在收到更改文件通知时将文件查找到该偏移量。下面是一个例子:

    主要方法:

    public static void Main(string[] args)
    {
        File.WriteAllLines("test.txt", new string[] { });
    
        new Thread(() => ReadFromFile()).Start();
    
        WriteToFile();
    }
    

    从文件读取方法:

    private static void ReadFromFile()
    {
        long offset = 0;
    
        FileSystemWatcher fsw = new FileSystemWatcher
        {
            Path = Environment.CurrentDirectory,
            Filter = "test.txt"
        };
    
        FileStream file = File.Open(
            "test.txt",
            FileMode.Open,
            FileAccess.Read,
            FileShare.Write);
    
        StreamReader reader = new StreamReader(file);
        while (true)
        {
            fsw.WaitForChanged(WatcherChangeTypes.Changed);
    
            file.Seek(offset, SeekOrigin.Begin);
            if (!reader.EndOfStream)
            {
                do
                {
                    Console.WriteLine(reader.ReadLine());
                } while (!reader.EndOfStream);
    
                offset = file.Position;
            }
        }
    }
    

    写入文件方法:

    private static void WriteToFile()
    {
        for (int i = 0; i < 100; i++)
        {
            FileStream writeFile = File.Open(
                "test.txt",
                FileMode.Append,
                FileAccess.Write,
                FileShare.Read);
    
            using (FileStream file = writeFile)
            {
                using (StreamWriter sw = new StreamWriter(file))
                {
                    sw.WriteLine(i);
                    Thread.Sleep(100);
                }
            }
        }
    }
    

    【讨论】:

    • 在文件操作方面我有点菜鸟。 seek 是将所有内容加载到内存中还是仅从偏移量加载到偏移量+长度?
    • 据我所知,seek 操作不会加载任何数据,只是将文件流定位在指定位置。在这种情况下,位置将是新数据开始的位置。
    猜你喜欢
    • 1970-01-01
    • 2016-07-11
    • 2023-03-12
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    相关资源
    最近更新 更多