我有一個經常更新(每分鐘約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