2013-08-14 2 views
1

C#에서 .txt 파일을 읽고 싶지만 동시에 모든 행을 읽지는 않습니다. 예를 들어 500 줄의 텍스트 파일을 생각해보십시오. 매번 25 번 실행하고 20 번 연속으로 읽는 기능이 필요합니다. 함수의 첫 번째 호출에서 1에서 20까지의 행을 읽고 두 번째로 호출하면 21-40이 읽혀집니다. 간단한 코드 아래C# 읽기 스트림

는 C에서이 작업을 수행 ++하지만 C#으로 그것을 달성하는 방법을 모른다 :

string readLines(ifstream& i) 
{ 
    string totalLine="", line = ""; 
    for(int i = 0; i < 20; i++){ 
      getline(i, line); 

      totalLine += line; 
    } 
    return totalLine; 
} 

int main() 
{ 

    // ... 
    ifstream in; 
    in.open(filename.c_str()); 
    while(true){ 
     string next20 = readLines(in); 
     // so something with 20 lines. 
    } 
    // ... 

} 
+4

[방법 : 파일에서 텍스트 읽기 :] (http://msdn.microsoft.com/en-us/library/db5x7c0d.aspx) –

+0

C++에서 제공 한 코드는 all - 모든 줄을 읽는 것을 반복합니다. 그것은 C#에서도 쉽게 할 수 있습니다. foreach (File.ReadLines (...)에서 문자열 줄). C#에서는 일괄 처리가 너무 나쁘지 않습니다 ... –

+0

이것은 간단한 예입니다. 필자가 의미하는 바는 while 문을 함수에 넣었을 때조차도 파일 읽기를 중간에 끝내더라도 중단 한 부분부터 계속 진행한다는 것입니다. –

답변

3

다양한 옵션이 여기에 있습니다,하지만 하나의 간단한 방법은 다음과 같습니다

using (var reader = File.OpenText("file.txt")) 
{ 
    for (int i = 0; i < 25; i++) 
    { 
     HandleLines(reader); 
    } 
} 

... 

private void HandleLines(TextReader reader) 
{ 
    for (int i = 0; i < 20; i++) 
    { 
     string line = reader.ReadLine(); 
     if (line != null) // Handle the file ending early 
     { 
      // Process the line 
     } 
    } 
} 
0

죄송합니다. GROUPBY은 게으르게 평가하지 않습니다, 그래서 이것은 탐욕 당신은 너무 같은 일괄() 메소드를 쓸 수있는 전체 파일

var twentyLineGroups = 
    File.ReadLines(somePath) 
     .Select((line, index) => new {line, index}) 
     .GroupBy(x => x.index/20) 
     .Select(g => g.Select(x => x.line)); 

foreach(IEnumerable<string> twentyLineGroup in twentyLineGroups) 
{ 
    foreach(string line in twentyLineGroup) 
    { 
     //tada! 
    } 
} 

+0

이 코드 조각은 실제로 라인을 20으로 나눈 다음 그룹을 반복하면서 라인을 반복합니다. 맞습니까? 첫 번째 문장의 기능에 익숙하지 않습니다. –

1

를 소비합니다

public static IEnumerable<string> Batch(IEnumerable<string> input, int batchSize) 
{ 
    int n = 0; 
    var block = new StringBuilder(); 

    foreach (var line in input) 
    { 
     block.AppendLine(line); 

     if (++n != batchSize) 
      continue; 

     yield return block.ToString(); 
     block.Clear(); 
     n = 0; 
    } 

    if (n != 0) 
     yield return block.ToString(); 
} 

그리고 전화를 좋아요 :

string filename = "<Your filename goes here>"; 
var batches = Batch(File.ReadLines(filename), 20); 

foreach (var block in batches) 
{ 
    Console.Write(block); 
    Console.WriteLine("------------------------"); 
} 
2

최소 횟수 가능LineRead()를 호출하려는 경우 당신은 최소 메모리 사용량 먼저 색인 파일의 라인 수 원하는 :

  1. 파일을 한 번하고 지수를 구문 분석 각 행의 위치는 FileStream입니다.
  2. ReadLine()을 원하는 위치에서만 호출하십시오.

예 :

// Parse the file 
var indexes = new List<long>(); 
using (var fs = File.OpenRead("text.txt")) 
{ 
    indexes.Add(fs.Position); 
    int chr; 
    while ((chr = fs.ReadByte()) != -1) 
    { 
     if (chr == '\n') 
     {       
      indexes.Add(fs.Position); 
     } 
    } 
} 

int minLine = 21; 
int maxLine = 40; 

// Read the line 
using (var fs = File.OpenRead("text.txt")) 
{ 
    for(int i = minLine ; i <= maxLine ; i++) 
    { 
     fs.Position = indexes[ i ]; 
     using (var sr = new StreamReader(fs)) 
      Console.WriteLine(sr.ReadLine()); 

} 

건배!