FileSystemWatcher和文本文件的最后一行

时间:2014-07-24 04:02:07

标签: c# text-files filesystemwatcher

我正在尝试在我的应用程序的Windows服务中添加FileSystemWatcher。在我的情况下,我有一个文本文件,它可以连续更新,可能是一行或多行,每次文件更新时我需要读取以前没有读过的所有文本文件行。

我咕噜咕噜地知道这个

File.ReadText(@"C:\Filename.txt").Last();
一旦文件更新,

将给我文本文件的最后一行,但我不确定它是否会给出所有未读行或仅文本文件的最后一行。同时我的文本文件逐行更新。

在任何一种情况下,什么是可能的解决方案。

如果文本文件逐行更新,FileSystemWatcher也会多次看到将最后一行添加到文件中。

请帮帮我。

更新了代码..

using (var sr = new StreamReader(@"C:\Temp\LineTest.txt")) 
{
    string line;
    long pos = 0;
    while ((line = sr.ReadLine()) != null) 
    {
        Console.Write("{0:d3} ", pos);
        Console.WriteLine(line);
        pos += line.Length;
    }
}

更新了代码。

 public partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
    }

    private System.Threading.Thread _thread;
    private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
    int lineCount;
    long previousLength = 0;
    string filepath = "C:\\Temp\\LineTest.txt";


    public void OnDebug()
    {

        OnStart(null);

    }

    protected override void OnStart(string[] args)
    {

        _thread = new Thread(addLogic);
        _thread.Start();


    }

    //This event is raised when a file is changed
    private void Watcher_Changed(object sender, FileSystemEventArgs e)
    {
        _thread = new Thread(addlogic);
        _thread.Start();
    }


    public static string[] ReadFromFile(string filePath, int count, ref int lineCount)
    {
        lineCount += count;
        return File.ReadLines(filePath).Skip(lineCount).Take(count).ToArray();
    }
    public void addlogic()
    {
       //Add Logic Here
       //How to use lineCount here to read specific line that i am not getting

            //If all textfile gets traversed then is FileSystemWatcher
            FileSystemWatcher Watcher = new FileSystemWatcher(filepath);
            Watcher.EnableRaisingEvents = true;
            Watcher.Changed += new FileSystemEventHandler(Watcher_Changed);

        }
    }



    protected override void OnStop()
    {
        _shutdownEvent.Set();
        _thread.Join();  // wait for thread to stop
    }
        }
    }

2 个答案:

答案 0 :(得分:2)

这是一个基于bansi在评论中建议的想法。它会记录已读入的行数,并将新行添加到文本框中。如果你的文件非常大,这可能会变得笨拙。

private int linesProcessed;  //Variable for keeping track of your line position

private void ProcessFile( string filePath)
{
    string[] lines = File.ReadAllLines(filePath);
    if (linesProcessed != lines.Count())  //Make sure a new line was entered 
    {
        for (int i = linesProcessed ; i < lines.Count(); i++)
        {
            textBox1.AppendText(lines[i] + "\n") ;  
            linesProcessed += 1;
        }
    }
}

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
{
   ProcessFile("c:\\temp\\test.txt");  //your file name here
}

修改了OP改变的代码。将位置变量放在循环之外,这样每次运行方法时都不会重置它。

long pos = 0;
private void ProcessFile( string filePath)
{
    using (var sr = new StreamReader(filePath))
    {
        string line;

        long count = 0;
        while ((line = sr.ReadLine()) != null)
        {
            count += 1;
            if (pos < count)
            {
                Console.Write("{0:d3} ", pos);
                Console.WriteLine(line);
                pos += 1;
            }
        }
    }
}

答案 1 :(得分:2)

我刚写了一个简单的类来阅读添加的行。这实际上读取了连接到文件的任何内容,即使是在同一行。

public class AddedContentReader
{

    private readonly FileStream _fileStream;
    private readonly StreamReader _reader;

    //Start position is from where to start reading first time. consequent read are managed by the Stream reader
    public AddedContentReader(string fileName, long startPosition = 0)
    {
        //Open the file as FileStream
        _fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        _reader = new StreamReader(_fileStream);
        //Set the starting position
        _fileStream.Position = startPosition;
    }


    //Get the current offset. You can save this when the application exits and on next reload
    //set startPosition to value returned by this method to start reading from that location
    public long CurrentOffset
    {
        get { return _fileStream.Position; }
    }

    //Returns the lines added after this function was last called
    public string GetAddedLines()
    {
        return _reader.ReadToEnd();
    }


}

你可以这样称呼它。

private AddedContentReader _freader;

protected override void OnStart(string[] args)
{
    _freader = new AddedContentReader("E:\\tmp\\test.txt");
    //If you have saved the last position when the application did exit then you can use that value here to start from that location like the following
    //_freader = new AddedContentReader("E:\\tmp\\test.txt",lastReadPosition);

}
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
    string addedContent= _freader.GetAddedLines();
    //you can do whatever you want with the lines
}

注意:我没有通过非常快速的更新来测试它。