Parsing CSV files in C#, with header

后端 未结 17 1624
悲哀的现实
悲哀的现实 2020-11-21 06:57

Is there a default/official/recommended way to parse CSV files in C#? I don\'t want to roll my own parser.

Also, I\'ve seen instances of people using ODBC/OLE DB to

相关标签:
17条回答
  • 2020-11-21 07:14

    In a business application, i use the Open Source project on codeproject.com, CSVReader.

    It works well, and has good performance. There is some benchmarking on the link i provided.

    A simple example, copied from the project page:

    using (CsvReader csv = new CsvReader(new StreamReader("data.csv"), true))
    {
        int fieldCount = csv.FieldCount;
        string[] headers = csv.GetFieldHeaders();
    
        while (csv.ReadNextRecord())
        {
            for (int i = 0; i < fieldCount; i++)
                Console.Write(string.Format("{0} = {1};", headers[i], csv[i]));
    
            Console.WriteLine();
        }
    }
    

    As you can see, it's very easy to work with.

    0 讨论(0)
  • 2020-11-21 07:14

    I have written TinyCsvParser for .NET, which is one of the fastest .NET parsers around and highly configurable to parse almost any CSV format.

    It is released under MIT License:

    • https://github.com/bytefish/TinyCsvParser

    You can use NuGet to install it. Run the following command in the Package Manager Console.

    PM> Install-Package TinyCsvParser
    

    Usage

    Imagine we have list of Persons in a CSV file persons.csv with their first name, last name and birthdate.

    FirstName;LastName;BirthDate
    Philipp;Wagner;1986/05/12
    Max;Musterman;2014/01/02
    

    The corresponding domain model in our system might look like this.

    private class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
    }
    

    When using TinyCsvParser you have to define the mapping between the columns in the CSV data and the property in you domain model.

    private class CsvPersonMapping : CsvMapping<Person>
    {
    
        public CsvPersonMapping()
            : base()
        {
            MapProperty(0, x => x.FirstName);
            MapProperty(1, x => x.LastName);
            MapProperty(2, x => x.BirthDate);
        }
    }
    

    And then we can use the mapping to parse the CSV data with a CsvParser.

    namespace TinyCsvParser.Test
    {
        [TestFixture]
        public class TinyCsvParserTest
        {
            [Test]
            public void TinyCsvTest()
            {
                CsvParserOptions csvParserOptions = new CsvParserOptions(true, new[] { ';' });
                CsvPersonMapping csvMapper = new CsvPersonMapping();
                CsvParser<Person> csvParser = new CsvParser<Person>(csvParserOptions, csvMapper);
    
                var result = csvParser
                    .ReadFromFile(@"persons.csv", Encoding.ASCII)
                    .ToList();
    
                Assert.AreEqual(2, result.Count);
    
                Assert.IsTrue(result.All(x => x.IsValid));
    
                Assert.AreEqual("Philipp", result[0].Result.FirstName);
                Assert.AreEqual("Wagner", result[0].Result.LastName);
    
                Assert.AreEqual(1986, result[0].Result.BirthDate.Year);
                Assert.AreEqual(5, result[0].Result.BirthDate.Month);
                Assert.AreEqual(12, result[0].Result.BirthDate.Day);
    
                Assert.AreEqual("Max", result[1].Result.FirstName);
                Assert.AreEqual("Mustermann", result[1].Result.LastName);
    
                Assert.AreEqual(2014, result[1].Result.BirthDate.Year);
                Assert.AreEqual(1, result[1].Result.BirthDate.Month);
                Assert.AreEqual(1, result[1].Result.BirthDate.Day);
            }
        }
    }
    

    User Guide

    A full User Guide is available at:

    • http://bytefish.github.io/TinyCsvParser/
    0 讨论(0)
  • 2020-11-21 07:14

    Here is a short and simple solution.

                    using (TextFieldParser parser = new TextFieldParser(outputLocation))
                     {
                            parser.TextFieldType = FieldType.Delimited;
                            parser.SetDelimiters(",");
                            string[] headers = parser.ReadLine().Split(',');
                            foreach (string header in headers)
                            {
                                dataTable.Columns.Add(header);
                            }
                            while (!parser.EndOfData)
                            {
                                string[] fields = parser.ReadFields();
                                dataTable.Rows.Add(fields);
                            }
                        }
    
    0 讨论(0)
  • 2020-11-21 07:15

    Let a library handle all the nitty-gritty details for you! :-)

    Check out FileHelpers and stay DRY - Don't Repeat Yourself - no need to re-invent the wheel a gazillionth time....

    You basically just need to define that shape of your data - the fields in your individual line in the CSV - by means of a public class (and so well-thought out attributes like default values, replacements for NULL values and so forth), point the FileHelpers engine at a file, and bingo - you get back all the entries from that file. One simple operation - great performance!

    0 讨论(0)
  • 2020-11-21 07:15

    If you need only reading csv files then I recommend this library: A Fast CSV Reader
    If you also need to generate csv files then use this one: FileHelpers

    Both of them are free and opensource.

    0 讨论(0)
  • 2020-11-21 07:19

    Some time ago I had wrote simple class for CSV read/write based on Microsoft.VisualBasic library. Using this simple class you will be able to work with CSV like with 2 dimensions array. You can find my class by the following link: https://github.com/ukushu/DataExporter

    Simple example of usage:

    Csv csv = new Csv("\t");//delimiter symbol
    
    csv.FileOpen("c:\\file1.csv");
    
    var row1Cell6Value = csv.Rows[0][5];
    
    csv.AddRow("asdf","asdffffff","5")
    
    csv.FileSave("c:\\file2.csv");
    

    For reading header only you need is to read csv.Rows[0] cells :)

    0 讨论(0)
提交回复
热议问题