[C#] C #을 사용하여 CSV 파일 읽기

간단한 가져 오기 응용 프로그램을 작성 중이며 CSV 파일을 읽고 결과를 DataGrid표시하고 손상된 그리드 파일을 다른 그리드에 표시해야합니다. 예를 들어 다른 그리드에서 5보다 짧은 선을 표시하십시오. 나는 이것을 이렇게하려고 노력하고있다 :

StreamReader sr = new StreamReader(FilePath);
importingData = new Account();
string line;
string[] row = new string [5];
while ((line = sr.ReadLine()) != null)
{
    row = line.Split(',');

    importingData.Add(new Transaction
    {
        Date = DateTime.Parse(row[0]),
        Reference = row[1],
        Description = row[2],
        Amount = decimal.Parse(row[3]),
        Category = (Category)Enum.Parse(typeof(Category), row[4])
    });
}

그러나이 경우에는 어레이에서 작동하기가 매우 어렵습니다. 값을 나누는 더 좋은 방법이 있습니까?



답변

바퀴를 재발 명하지 마십시오. .NET BCL에 이미있는 기능을 활용하십시오.

  • 에 대한 참조를 추가하십시오 Microsoft.VisualBasic(예, VisualBasic이라고하지만 C #에서도 작동합니다. 결국 모두 IL 일뿐입니다)
  • Microsoft.VisualBasic.FileIO.TextFieldParser클래스를 사용하여 CSV 파일을 구문 분석하십시오.

샘플 코드는 다음과 같습니다.

using (TextFieldParser parser = new TextFieldParser(@"c:\temp\test.csv"))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    while (!parser.EndOfData)
    {
        //Processing row
        string[] fields = parser.ReadFields();
        foreach (string field in fields)
        {
            //TODO: Process field
        }
    }
}

C # 프로젝트에서 나에게 효과적입니다.

더 많은 링크 / 정보는 다음과 같습니다.


답변

내 경험은 많은 다른 CSV 형식이 있다는 것입니다. 특히 필드 내에서 따옴표와 구분 기호 이스케이프 처리 방법.

이것들은 내가 만난 변종입니다.

  • 따옴표는 따옴표로 묶어지고 두 배가됩니다 (예 : 15 “-> field1,”15 “” “, field3
  • 다른 이유로 필드를 인용하지 않으면 따옴표는 변경되지 않습니다. 즉 15 “-> field1,15”, fields3
  • 따옴표는 \로 이스케이프됩니다. 즉 15 “-> field1,”15 \ “”, field3
  • 따옴표는 전혀 변경되지 않습니다 (항상 올바르게 구문 분석 할 수있는 것은 아닙니다)
  • 구분자는 따옴표로 묶습니다 (excel). 즉 a, b-> field1, “a, b”, field3
  • 구분 기호는 \로 이스케이프됩니다. 즉 a, b-> field1, a \, b, field3

기존 csv 파서 중 많은 것을 시도했지만 내가 실행 한 변형을 처리 할 수있는 단일 파서는 없습니다. 파서가 지원하는 이스케이프 변형을 문서에서 찾아내는 것도 어렵습니다.

내 프로젝트에서 VB TextFieldParser 또는 사용자 지정 스플리터를 사용합니다.


답변

Nuget의 CsvHelper를 권장 합니다.

(Microsoft.VisualBasic에 대한 참조를 추가하는 것은 옳지 않다고 생각합니다. 추악한 것뿐만 아니라 아마도 크로스 플랫폼이 아닙니다.)


답변

때로는 바퀴를 재발 명하고 싶지 않을 때 라이브러리를 사용하는 것이 좋지만,이 경우 라이브러리를 사용하는 것보다 적은 수의 코드 줄로 동일한 작업을 수행 할 수 있습니다. 사용하기 매우 쉬운 다른 방법이 있습니다.

  1. 이 예제에서는 StreamReader를 사용하여 파일을 읽습니다.
  2. 각 줄에서 구분자를 감지하는 정규식.
  3. 인덱스 0에서 n까지 열을 수집하는 배열

using (StreamReader reader = new StreamReader(fileName))
    {
        string line;

        while ((line = reader.ReadLine()) != null)
        {
            //Define pattern
            Regex CSVParser = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");

            //Separating columns to array
            string[] X = CSVParser.Split(line);

            /* Do something with X */
        }
    }


답변

CSV는 복잡 얻을 수있는 진짜 빨리.

강력하고 잘 테스트 된 것을 사용하십시오.
FileHelpers :
www.filehelpers.net

FileHelper는 파일, 문자열 또는 스트림의 고정 길이 또는 구분 된 레코드에서 데이터를 가져 오거나 내보내는 무료 .NET 라이브러리입니다.


답변

나는 이것을 여기에서 사용한다 :

http://www.codeproject.com/KB/database/GenericParser.aspx

지난번에 이런 것을 찾고 있었을 때이 질문에 대한 답으로 찾았습니다 .


답변

이 목록의 또 다른 하나 인 Cinchoo ETL -CSV 파일을 읽고 쓰는 오픈 소스 라이브러리

아래 샘플 CSV 파일

Id, Name
1, Tom
2, Mark

아래와 같이 라이브러리를 사용하여 빠르게로드 할 수 있습니다

using (var reader = new ChoCSVReader("test.csv").WithFirstLineHeader())
{
   foreach (dynamic item in reader)
   {
      Console.WriteLine(item.Id);
      Console.WriteLine(item.Name);
   }
}

CSV 파일과 일치하는 POCO 클래스가있는 경우

public class Employee
{
   public int Id { get; set; }
   public string Name { get; set; }
}

아래와 같이 CSV 파일을로드 할 수 있습니다

using (var reader = new ChoCSVReader<Employee>("test.csv").WithFirstLineHeader())
{
   foreach (var item in reader)
   {
      Console.WriteLine(item.Id);
      Console.WriteLine(item.Name);
   }
}

CodeProject 에서 사용 방법에 대한 기사를 확인 하십시오.

면책 조항 : 나는이 도서관의 저자입니다