2010-06-24 4 views
0

구문 분석해야하는 탭으로 구분 된 텍스트 파일이 수신됩니다. 구문 분석이 끝나면 부품을 특정 열에 지정해야합니다.텍스트 파일을 구문 분석하고 열을 부분에 할당하십시오.

string path = "C:\\Users\\Robert\\Desktop\\Test.txt"; 

    FileInfo fileInfo = new FileInfo(path); 

    using (StreamReader streamReader = fileInfo.OpenText()) 
    { 
     string line = ""; 

     while ((line = streamReader.ReadLine()) != null) 
     { 
      string[] columns = line.Split('\t'); 

      Output0Buffer.AddRow(); 
      Output0Buffer.Column0 = columns[0]; 
      Output0Buffer.Column1 = columns[1]; 
      Output0Buffer.Column2 = columns[2]; 
      Output0Buffer.Column3 = columns[3]; 
      Output0Buffer.Column4 = columns[4]; 
     } 
    } 

이 코드가 실패 이것에 대한 문제는 텍스트 파일의 라인 중 일부는 5 열을하지 않아도되며, 다음은

내가이 일을 사용하고 코드의 예입니다 Column4에 열의 값을 할당하려고 시도하면 (실제로는 실제 파일에 21 개의 부분이 있으므로 오류가 발생하기 쉽습니다).

실제 데이터가있는 경우 어떻게 값을 Column4 (5,6 - 21)에만 할당 할 수 있습니까? 또한 for 또는 foreach 루프로 작성하여 조금 더 세련되게 만들 수 있습니까? 그래서 21 열 모두에 대해 줄을 가질 필요가 없습니까?

도움을 주시면 대단히 감사하겠습니다.

답변

3

가장 간단한 건에 대한의 값을 출력 버퍼 유형에 열 모음을 추가 한 다음 설정하는 것입니다 ...이 같은 것 루프 예

for(int i = 0; i < columns.Length; i++) 
{ 
    Output0Buffer.Columns[i] = columns[i]; 
} 

그 종류와 특성 명명 규칙의 일관성을 변경할 수없는 경우 (즉, column1,2,3이 ... n은) 다음 반사하지만 각 속성에 설정할 수 있습니다 :

Type buffType = Output0Buffer.GetType(); 
for(int i = 0; i < columns.Length; i++) 
{ 
    string propertyName = String.Format("Column{0}", i); 
    PropertyInfo pi = buffType.GetProperty(propertyName); 
    pi.SetValue(buffer, columns[i], null); 
} 
+0

감사를 너,이 ... 완벽하게 작동 했어! – Sesame

1

당신은 우리에게 Output0Buffer의 정의를 말하지 않았지만, 가장 확실한 해결책을 허용하도록 정의를 변경하는 것 같은 색인 :

int maxCol = Math.Min(columns.Length,Output0Buffer.Columns.Count); 
for(int colIDx=0;colIdx<maxCol;++colIdx) 
    Output0Buffer.Columns[colIdx]=columns[colIdx]; 

(즉, "에어 코드"했다, 조심하십시오.)

0

당신은

Output0Buffer.AddRow() 
for (ix = 0; ix < column.Length; ix++) 
{ 
    switch(ix) 
    { case 0: 
     Output0Buffer.Column0 = columns[ix]; 
     break; 
     case 1: 
     ... 
    } 
} 

같은이 당신의 OutputBuffer에서 열 등 Column0, 열 1로 명명 할 수 있습니까? 배열이 될 수없는 이유가 있습니까? 가능한 경우 위의 전체 switch 문에 대해

Output0Buffer.Columns[ix] = columns[ix]; 

을 사용할 수 있습니다. 개별적으로 이름을 지정해야하는 경우 리플렉션을 사용하여 [ix] 열에 해당하는 각 열의 인스턴스 멤버를 가져와야한다고 생각합니다.

확실치 않지만 AutoMapper가 이와 같은 문제를 처리 할 가능성이 있습니다. 당신은 그것을 조사 할 것입니다.

0

사용하려고 시도 할 수있는 .Split(...)에 과부하가 있습니다.

string[] columns = (line + "\t\t\t\t").Split(new [] {'\t'}, 5); 

Output0Buffer.AddRow(); 
Output0Buffer.Column0 = columns[0]; 
Output0Buffer.Column1 = columns[1]; 
Output0Buffer.Column2 = columns[2]; 
Output0Buffer.Column3 = columns[3]; 

// The trim is needed on this line because the split method 
// will stop processing after it has hit the number of elements 
// listed in the count value 
Output0Buffer.Column4 = columns[4].TrimEnd('\t'); 

는 ... 또 다른 옵션은

var parts = line.Split('\t'); 
var columns = new string[5]; 
if (parts.Length > columns.Length) 
    throw new InvalidOperationException(); 
Array.Copy(parts, columns, parts.Length); 

// the rest of your code goes here 
관련 문제