2017-04-03 75 views
2

我是的新手,我正在研究一個應用程序,它顯示文本文件上最後兩行的兩個日期的時差。從文本中讀取最後2行

我想從文件文本中讀取最後一行,我已經知道如何讀取最後一行,但我需要閱讀最後一行。

這是我的代碼:

var lastLine = File.ReadAllLines("C:\\test.log").Last(); 
       richTextBox1.Text = lastLine.ToString(); 

回答

3

由於

File.ReadAllLines("C:\\test.log"); 

返回陣列你可以把數組的最後兩個項目:

var data = File.ReadAllLines("C:\\test.log"); 

string last = data[data.Length - 1]; 
string lastButOne = data[data.Length - 2]; 

一般情況下與文件(這就是爲什麼ReadAllLines是一個不錯的選擇)你可以實現

public static partial class EnumerableExtensions { 
    public static IEnumerable<T> Tail<T>(this IEnumerable<T> source, int count) { 
    if (null == source) 
     throw new ArgumentNullException("source"); 
    else if (count < 0) 
     throw new ArgumentOutOfRangeException("count"); 
    else if (0 == count) 
     yield break; 

    Queue<T> queue = new Queue<T>(count + 1); 

    foreach (var item in source) { 
     queue.Enqueue(item); 

     if (queue.Count > count) 
     queue.Dequeue(); 
    } 

    foreach (var item in queue) 
     yield return item; 
    } 
} 

...

var lastTwolines = File 
    .ReadLines("C:\\test.log") // Not all lines 
    .Tail(2); 
+0

ty此工作完美 –

2

你可以嘗試這樣做

var lastLines = File.ReadAllLines("C:\\test.log").Reverse().Take(2).Reverse(); 

但是這取決於你的文件有多大有可能是更有效的方法來處理這個比讀取所有行立刻。見Get last 10 lines of very large text file > 10GBHow to read last 「n」 lines of log file

+0

反轉while文件,取兩個元素並將其反轉一次?對我來說似乎很奇怪,但應該工作。 – HimBromBeere

+0

只有當你關心線條的順序時,才需要第二個反轉,從她的問題描述中猜測它可能不是必需的,但只是給出一個包含它的完整答案。 – Staeff

2

簡單的ReadAllLines結果存儲到一個變量,不是拿兩個最後的:

var allText = File.ReadAllLines("C:\\test.log"); 
var lastLines = allText.Skip(allText.Length - 2); 
1

您可以使用Skip()Take()

var lastLine = File.ReadAllLines("C:\\test.log"); 
var data = lastLine.Skip(lastLine.Length - 2); 
       richTextBox1.Text = lastLine.ToString(); 
+0

你的'Take'是多餘的,因爲跳過後你知道你只剩下2件東西了。 – Chris

+0

@克里斯,是真的...編輯。感謝您的支持 – Rahul

1

您可以使用StreamReader結合使用Queue<string>,因爲您必須以任何方式讀取整個文件。

// if you want to read more lines change this to the ammount of lines you want 
const int LINES_KEPT = 2; 

Queue<string> meQueue = new Queue<string>(); 
using (StreamReader reader = new StreamReader(File.OpenRead("C:\\test.log"))) 
{ 
    string line = string.Empty; 
    while ((line = reader.ReadLine()) != null) 
    { 
     if (meQueue.Count == LINES_KEPT ) 
      meQueue.Dequeue(); 

     meQueue.Enqueue(line); 
    } 
} 

現在你可以用這兩條線像這樣:

string line1 = meQueue.Dequeue(); 
string line2 = meQueue.Dequeue(); // <-- this is the last line. 

或者把它添加到RichTextBox

​​

使用File.ReadAllLines將讀取整個文本,然後使用Linq將迭代已經有紅線。此方法在一次運行中完成所有操作。

2

以前所有的答案返回所請求的最後幾行之前熱切加載所有的文件在內存中。如果文件很大,這可能是個問題。幸運的是,它很容易避免。

public static IEnumerable<string> ReadLastLines(string path, int count) 
{ 
    if (count < 1) 
     return Enumerable.Empty<string>(); 

    var queue = new Queue<string>(count); 

    foreach (var line in File.ReadLines(path)) 
    { 
     if (queue.Count == count) 
      queue.Dequeue(); 

     queue.Enqueue(line); 
    } 

    return queue; 
} 

這隻會保存在內存中的最後n讀取線避免使用大文件存儲問題。

+0

您仍然需要遍歷所有對大文件無效的行。在我的答案中查看鏈接的問題。 – Staeff

+0

@Staeff當然是的,但是它的數量級比實際將整個文件加載到內存中更有效,這是基於'ReadAllLines'的其他解決方案所做的。 – InBetween

+0

@InBetween但仍然使用'StreamReader'會更有效率,正如我在回答中所述。當你只需要最後兩行時加載整個文件是沒有意義的。 –

1
string line; 
string[] lines = new string[]{"",""}; 
int index = 0; 
using (StreamReader reader = new StreamReader(File.OpenRead("C:\\test.log"))) 
{ 
    while ((line = reader.ReadLine()) != null) 
    { 
     lines[index] = line; 
     index = 1-index; 
    } 
} 
// Last Line -1 = lines[index] 
// Last line = lines[1-index]