我有一个经常更新(每分钟约20至30次)的.csv文件。我想在写入文件后立即将新添加的行插入到数据库中。使用.NET实时读取文件中的更改内容
FileSystemWatcher类监听文件系统更改通知,并可以在指定文件发生更改时引发事件。问题是FileSystemWatcher无法确定哪些行被添加或删除(据我所知)。
读取这些行的一种方法是保存并比较更改之间的行数,并读取最后一次和最后一次更改之间的差异。不过,我正在寻找更清洁(也许更优雅)的解决方案。
我有一个经常更新(每分钟约20至30次)的.csv文件。我想在写入文件后立即将新添加的行插入到数据库中。使用.NET实时读取文件中的更改内容
FileSystemWatcher类监听文件系统更改通知,并可以在指定文件发生更改时引发事件。问题是FileSystemWatcher无法确定哪些行被添加或删除(据我所知)。
读取这些行的一种方法是保存并比较更改之间的行数,并读取最后一次和最后一次更改之间的差异。不过,我正在寻找更清洁(也许更优雅)的解决方案。
我写了一些非常相似的东西。我使用FileSystemWatcher来获取有关更改的通知。然后,我使用FileStream读取数据(跟踪文件中的最后位置,并在读取新数据之前查找数据)。然后我将读取的数据添加到一个缓冲区,该缓冲区会自动提取完整的行,然后输出到UI。
注:“this.MoreData(..)是一个事件,听者其中增加了上述缓冲区,并处理完整的线条提取
注:正如已经提到的,这只会工作如果修改总是添加到文件。任何删除将导致问题。
希望这可以帮助。
public void File_Changed(object source, FileSystemEventArgs e)
{
lock (this)
{
if (!this.bPaused)
{
bool bMoreData = false;
// Read from current seek position to end of file
byte[] bytesRead = new byte[this.iMaxBytes];
FileStream fs = new FileStream(this.strFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
if (0 == this.iPreviousSeekPos)
{
if (this.bReadFromStart)
{
if (null != this.BeginReadStart)
{
this.BeginReadStart(null, null);
}
this.bReadingFromStart = true;
}
else
{
if (fs.Length > this.iMaxBytes)
{
this.iPreviousSeekPos = fs.Length - this.iMaxBytes;
}
}
}
this.iPreviousSeekPos = (int)fs.Seek(this.iPreviousSeekPos, SeekOrigin.Begin);
int iNumBytes = fs.Read(bytesRead, 0, this.iMaxBytes);
this.iPreviousSeekPos += iNumBytes;
// If we haven't read all the data, then raise another event
if (this.iPreviousSeekPos < fs.Length)
{
bMoreData = true;
}
fs.Close();
string strData = this.encoding.GetString(bytesRead);
this.MoreData(this, strData);
if (bMoreData)
{
File_Changed(null, null);
}
else
{
if (this.bReadingFromStart)
{
this.bReadingFromStart = false;
if (null != this.EndReadStart)
{
this.EndReadStart(null, null);
}
}
}
}
}
关闭我的头顶上,你可以存储最后一个已知的文件大小。检查文件大小,并在更改时打开阅读器。
然后请读者阅读您的最后一个文件大小,并从那里开始阅读。
只是因为文件大小保持不变并不意味着没有任何改变。哈希会更合适..或在这种情况下,使用FileSystemWatcher。 – mmcdole 2008-10-19 15:27:13
如果足够小,我会将当前文本保留在内存中,然后使用diff算法检查新文本和以前的文本是否更改。这个库,http://www.mathertel.de/Diff/,不仅会告诉你有什么改变,但改变了什么。所以你可以将更改后的数据插入到数据库中。
对,FileSystemWatcher不知道任何关于您文件内容的信息。它会告诉你它是否改变了,等等,但没有改变。
你只是添加到文件?从帖子中可以看出,是否添加了线条或者是否可以删除。假设他们被追加,解决方案非常简单,否则你会做一些比较。
你说得对FileSystemWatcher。您可以侦听创建,修改,删除等事件,但不会比引发它们的文件更深入。
你有控制文件本身吗?您可以稍微改变模型以像缓冲区一样使用文件。有两个,而不是一个文件。一个是分期,一个是所有已处理产出的总和。读取“缓冲区”文件中的所有行,处理它们,然后将它们插入另一个文件的末尾,这是所有处理行的总数。然后,删除你处理的行。这样,文件中的所有信息都处于待处理状态。问题在于,如果系统是写入以外的东西(即也删除行),那么它将不起作用。
我认为你应该使用NTFS更改日志或类似:
更改日志中使用NTFS来 提供对文件所做的卷上的所有 变化的持续日志。 对于每个卷,NTFS使用更改 日志到跟踪信息约 添加,删除和修改文件。 更改日志更多 比时间戳或文件 有效确定给定名称空间中的更改 的通知。
你可以找到一个description on TechNet。你将需要在.NET中使用PInvoke。
为什么downvote? – RichS 2014-11-05 11:54:23