2017-04-03 2 views
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있어 나쁜 선택) 구현할 수 있습니다

123,...

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

이 작업을 완벽하게 수행해 주셔서 감사합니다. –

2

당신은 모든 라인을 읽는 것보다이 문제를 처리하기 위해 아마 더 효율적인 방법이 있습니다이

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

을하려고하지만, 파일이 얼마나 큰에 따라 수 한 번에. Get last 10 lines of very large text file > 10GB 참조 How to read last “n” lines of log file

+0

while 파일을 뒤집어서 두 개의 요소를 가져 와서 다시 뒤집으시겠습니까? 이상하게 보이지만 일해야합니다. – HimBromBeere

+0

두 번째 반전은 줄의 순서를 신경 쓰는 경우에만 필요합니다. 문제 설명에서 짐작할 필요는 없을 지 모르겠지만, 나는 그것을 포함 시켰습니다. – Staeff

2

은 단순히 변수에 ReadAllLines의 결과를 저장하고 마지막 두 사람을보다 : 당신은 StreamReader을 사용할 수 있습니다

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

당신은

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

'Take'는 건너 뛴 후에 남은 아이템이 2 개 밖에 없으므로 불필요합니다. – Chris

+0

@Chris, 네, 사실 ... 편집했습니다. – Rahul

1

처럼 Skip()Take()을 사용할 수 있습니다 당신이 전체 파일을 어느쪽으로 든 읽어야하기 때문에 Queue<string>의 조합으로.

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

또는 RichTextBox에 이것을 추가 :

// 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); 
    } 
} 

지금 당신은 바로 그런 것처럼이 두 라인을 사용할 수 있습니다 File.ReadAllLines를 사용

richTextBox1.Text = string.Empty; // clear the text 
while (meQueue.Count != 0) 
{ 
    richTextBox1.Text += meQueue.Dequeue(); // add all lines in the same order as they were in file 
} 

사용 후 전체 텍스트를 읽을 것이다 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'를 사용하면보다 효율적으로 답변 할 수 있습니다. 마지막 줄이 2 개만 필요할 때 전체 파일을로드하는 것은 의미가 없습니다. –

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] 
관련 문제