2014-07-17 52 views
0

我確實檢查了是否存在與我的問題匹配的問題,但我沒有看到任何問題,如果我這樣做,我的錯誤。同時比較文本文件的高效方法

我有兩個文本文件可以相互比較,一個是有時被覆蓋的臨時日誌文件,另一個是永久日誌,它將收集並追加臨時日誌的所有內容到一個文件中(它將收集日誌中的新行,因爲它最後一次檢查並將新行添加到完整日誌的末尾)。然而,在一個點之後,這可能會導致完整的日誌變得相當大,因此不能比較有效地進行比較,所以我一直在考慮用不同的方法來處理這個問題。

我的第一個想法是「緩衝」臨時日誌(是它通常是兩者中的較小)的字符串到一個列表,簡單地通過歸檔日誌循環,這樣做:

List<String> bufferedlines = new List<string>(); 
using (StreamReader ArchiveStream = new StreamReader(ArchivePath)) 
{ 
    if (bufferedlines.Contains(ArchiveStream.ReadLine())) 
    { 

    } 
} 

現在有幾種方法可以從這裏開始,我可以創建另一個列表來存儲不一致的地方,關閉讀取流(我不確定您是否可以同時讀取和寫入,如果可以的話可能會讓我的選項變得更容易),然後以追加模式打開寫入流並將列表寫入文件。或者,切斷緩衝不一致性,我可以在文件進行比較時打開寫入流,並在現場寫入不匹配的行。

我能想到的另一種方法受限於我是否可以完成的知識,而不是緩衝任一文件,在讀取它們時並排比較流,並在飛行中追加行。喜歡的東西:

using (StreamReader ArchiveStream = new StreamReader(ArchivePath)) 
{ 
    using (StreamReader templogStream = new StreamReader(tempPath)) 
    { 
     if (!(ArchiveStream.ReadAllLines.Contains(TemplogStream.ReadLine()))) 
     { 
      //write the line to the file 
     } 
    } 
} 

正如我說我不知道​​是否會工作,或者它可能會比第一種方法更有效,所以我想我會問,看是否有人早已洞悉如何可能會得到適當的實施,以及它是否是最有效的方式,或者是否有更好的方法。

回答

2

實際上,您要在這裏得到的是一組不在另一組中的所有項目。這是設置減法,或以LINQ術語Except。如果你的數據集是足夠小,你可以簡單地這樣做:

var lines = File.ReadLines(TempPath) 
    .Except(File.ReadLines(ArchivePath)) 
    .ToList();//can't write to the file while reading from it 
File.AppendAllLines(ArchivePath, lines); 

當然,這個代碼需要把所有的臨時文件到內存中的線,因爲這只是如何Except實現。它會創建所有項目的HashSet,以便它可以有效地從其他序列中找到匹配項。

假設這裏需要添加的行數很少,所以我們在這裏找到的所有行都需要存儲在內存中這一事實不成問題。如果可能有一個批次,那麼除了第一個文件外,您還想將它們寫入另一個文件(如果需要,可能會在完成時將這兩個文件一起進行連接)。

+0

如果文件按不同順序具有相同的行集,會發生什麼情況? –

+0

@EdPlunkett然後代碼完全按照它應該的方式工作。訂單不在這裏考慮。 – Servy

+0

哦,好的,對不起。我沒有仔細閱讀OP。現在我懂了。 –