2009-11-06 1 views
1

내 고객 지정 소프트웨어에서 파일을 가져 오려고합니다. 이 파일은 기본적으로 사용자 정의 이스케이프 문자가 포함 된 csv 파일입니다. 나는 파일을 한 줄씩 읽은 다음 각 줄을 문자열 []로 나눕니다. 그런 다음 각 각 요소를 내 사용자 지정 개체의 필드에 할당합니다. 예를 들면 :C#을 사용하여 알 수없는 크기의 CSV를 사용자 지정 개체로 변환

Person.Name = line[0]; 
Person.Age = line[1]; 
Person.Height = line[2]; 

등 문제가, 내가 수입하고있는 파일 중 일부는 응용 프로그램의 이전 버전에서하고 모든 필드를 포함하지 않는다. 그래서이 줄 line.Length = 2 대신 3

의이 문제를 해결하는 "깨끗한"방법이 있나요 때문에

Person.Height = line[2]; 

오류를 알아? 나는 각 과제 앞에 if 문을 써서 주위를 둘러 보았고 [x] 행이 유효한지 확인했다. 그러나 그것은 나에게 kludgy처럼 보인다.

+0

일반적으로 6 개의 항목이 있다고하면 3 또는 5 중 누락 된 항목을 알 수있는 방법이 있습니까? 어떤 열이 누락되어 있는지 날짜 또는 무언가를 기준으로 말할 수있는 방법이 있습니까? – bytebender

+0

그래, 내 솔루션은 누락 된 열을 항상 줄 끝 부분에 의존합니다. 연속적인 버전이 단순히 더 많은 열을 추가하는 경우 합리적인 가정이라고 생각합니다. –

+0

이전/새 CSV에 헤더가 있습니까? –

답변

2

성능이 떨어지는 거대한 CSV를 파싱하지 않는다고 가정 할 때 몇 가지 제안 사항이 있습니다.

내가 사용하는 한 가지 접근법은 실제로 파일 작업의 일관성을 보장 할 수있는 데이터 작업을 시작하기 전에 한 가지 조치를 취하는 것입니다. 귀하의 경우에는 각 행을 스캔하여 모든 열이 있는지 확인하고 그렇지 않은 경우 누락 된 데이터의 기본값을 삽입하는 것입니다.

이렇게하면 "정리"코드가 데이터 처리와 분리되어있을 수 있습니다. 이것은 실제로 약간의 코딩 작업을 필요로하고 퍼포먼스 측면에서 볼 때 더 느릴 수 있습니다 (기본적으로 파일을 두 번 파싱하고 있기 때문에).하지만 코드를 두 가지 별도의 작업으로 분리하기 때문에 코드를 읽고 디버그하기가 쉽습니다.

다른 방법으로 LINQtoCSV과 같은 타사 라이브러리를 사용하여 "null 허용"열을 표시 할 수 있습니다. 그러면 인덱스 대신 명명 된 속성으로 열을 참조 할 수 있습니다.

1

좋아, 이것은 약간 벽에 있지만 작동 할 수 있습니다.

"줄"배열을 문자열 스택에로드하고 필드에 할당 할 때 각 항목을 스택에서 팝핑 할 수 있습니다. 물론, "누락 된 항목"이 있으면 줄 끝에서 누락 된 것으로 가정합니다. 더 이상 항목이없는 경우 분명히 Stack<T>의 "팝"메소드가 예외를 던질 것이기 때문에 나는 "PopOrDefault"확장 방법을 사용하고

var fields = new Stack<string>(line); 
Person.Name = fields.PopOrDefault(); 
Person.Age = fields.PopOrDefault(); 
Person.Height = fields.PopOrDefault(); 

:

그래서 여기에 생각입니다. 여기에 대한 구현 (꽤 솔직는)입니다 :

static class StackExtensions 
{ 
    public static T PopOrDefault<T>(this Stack<T> stack) 
    { 
     if (stack.Count == 0) return default(T); 
     return stack.Pop(); 
    } 
} 

그래서 어떤 필드가 누락 된 경우, (null의이 경우 문자열의 기본을) 해당 유형에 대한 기본 값을 얻을 것이다 재산 . "PopOrDefault"에 두 번째 매개 변수를 추가하여 자신의 기본값을 지정할 수도 있습니다.

0

얼마나 많은 버전의 csv 파일이 있습니까? 이것은 간단한 대답처럼 보인다,하지만 당신은 같은 것을 할 수있는 :

int OLD_VERSION_NUM_COLUMNS = 2; 
bool isOlderVersion = string.length == OLD_VERSION_NUM_COLUMNS; 

Person.Name = isOlderVersion ? line[0] : line[0]; 
Person.Age = isOlderVersion ? line[1] : line[1]; 
Person.Height = isOlderVersion ? 0 : line[2]; 
Person.Width = isOlderVersion ? line[2] : line[3]; 

이 매우 효율적이지 않다 당신이 힘들 것 (40) 열이있는 경우 읽을 수 있지만 개념이 확실히 일 것입니다.

2

오픈 소스 라이브러리 http://filehelpers.sourceforge.net/에서 CSV 파일 (및 기타 파일 유형)을 읽을 수도 있습니다. 누락 된 필드를 처리해야하며 선택적 필드를 지정할 수 있습니다.

관련 문제