C# 在.NET中读取文件内容更改

C# 在.NET中读取文件内容更改,c#,.net,file,ipc,filesystemwatcher,C#,.net,File,Ipc,Filesystemwatcher,在Linux中,很多IPC都是通过在一个进程中附加到一个文件并从另一个进程中读取新内容来完成的 我想在Windows/.NET中执行上述操作(太混乱,无法使用管道等普通IPC)。我将附加到Python进程中的一个文件中,我希望每次FileSystemWatcher报告事件时读取更改,并且仅读取更改。我不想每次查找更改时都将整个文件内容读入内存(文件将非常大) 每个追加操作都追加一行数据,该行数据以唯一的递增计数器(timestamp+key)开始,以换行结束 using (FileStr

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

我想在Windows/.NET中执行上述操作(太混乱,无法使用管道等普通IPC)。我将附加到Python进程中的一个文件中,我希望每次FileSystemWatcher报告事件时读取更改,并且仅读取更改。我不想每次查找更改时都将整个文件内容读入内存(文件将非常大)

每个追加操作都追加一行数据,该行数据以唯一的递增计数器(timestamp+key)开始,以换行结束

    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());            
            }
        }
    }

这将帮助您只读附加行

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

主要方法:

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);
            }
        }
    }
}
写入文件方法:

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);
            }
        }
    }
}
private static void WriteToFile()
{
对于(int i=0;i<100;i++)
{
FileStream writeFile=File.Open(
“test.txt”,
FileMode.Append,
FileAccess.Write,
文件共享(读取);
使用(FileStream file=writeFile)
{
使用(StreamWriter sw=新StreamWriter(文件))
{
sw.WriteLine(i);
睡眠(100);
}
}
}
}

说到文件操作,我有点不在行。seek是将所有内容加载到内存中,还是仅从偏移量加载到偏移量+长度?据我所知,seek操作不会加载任何数据,只是将文件流定位到指定位置。在这种情况下,位置将是新数据的起点。一个伟大的解决方案,简短而致命!