我正在尝试在我的应用程序的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
}
}
}
答案 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
}
注意:我没有通过非常快速的更新来测试它。