Very simple C# CSV reader

后端 未结 7 1401
渐次进展
渐次进展 2020-11-27 15:08

I\'d like to create an array from a CSV file.

This is about as simple as you can imagine, the CSV file will only ever have one line and these values:



        
相关标签:
7条回答
  • 2020-11-27 15:41

    This is what I used in a project, parses a single line of data.

        private string[] csvParser(string csv, char separator = ',')
        {
            List <string> = new <string>();
            string[] temp = csv.Split(separator);
            int counter = 0;
            string data = string.Empty;
            while (counter < temp.Length)
            {
                data = temp[counter].Trim();
                if (data.Trim().StartsWith("\""))
                {
                    bool isLast = false;
                    while (!isLast && counter < temp.Length)
                    {
                        data += separator.ToString() + temp[counter + 1];
                        counter++;
                        isLast = (temp[counter].Trim().EndsWith("\""));
                    }
                }
                parsed.Add(data);
                counter++;
            }
    
            return parsed.ToArray();
    
        }
    

    http://zamirsblog.blogspot.com/2013/09/c-csv-parser-csvparser.html

    0 讨论(0)
  • 2020-11-27 15:43

    Here's a simple function I made. It accepts a string CSV line and returns an array of fields:

    It works well with Excel generated CSV files, and many other variations.

        public static string[] ParseCsvRow(string r)
        {
    
            string[] c;
            string t;
            List<string> resp = new List<string>();
            bool cont = false;
            string cs = "";
    
            c = r.Split(new char[] { ',' }, StringSplitOptions.None);
    
            foreach (string y in c)
            {
                string x = y;
    
    
                if (cont)
                {
                    // End of field
                    if (x.EndsWith("\""))
                    {
                        cs += "," + x.Substring(0, x.Length - 1);
                        resp.Add(cs);
                        cs = "";
                        cont = false;
                        continue;
    
                    }
                    else
                    {
                        // Field still not ended
                        cs += "," + x;
                        continue;
                    }
                }
    
                // Fully encapsulated with no comma within
                if (x.StartsWith("\"") && x.EndsWith("\""))
                {
                    if ((x.EndsWith("\"\"") && !x.EndsWith("\"\"\"")) && x != "\"\"")
                    {
                        cont = true;
                        cs = x;
                        continue;
                    }
    
                    resp.Add(x.Substring(1, x.Length - 2));
                    continue;
                }
    
                // Start of encapsulation but comma has split it into at least next field
                if (x.StartsWith("\"") && !x.EndsWith("\""))
                {
                    cont = true;
                    cs += x.Substring(1);
                    continue;
                }
    
                // Non encapsulated complete field
                resp.Add(x);
    
            }
    
            return resp.ToArray();
    
        }
    
    0 讨论(0)
  • 2020-11-27 15:45

    This fixed version of code above remember the last element of CVS row ;-)

    (tested with a CSV file with 5400 rows and 26 elements by row)

       public static string[] CSVRowToStringArray(string r, char fieldSep = ',', char stringSep = '\"')  {
                bool bolQuote = false;
                StringBuilder bld = new StringBuilder();
                List<string> retAry = new List<string>();
    
                foreach (char c in r.ToCharArray())
                    if ((c == fieldSep && !bolQuote))
                    {
                        retAry.Add(bld.ToString());
                        bld.Clear();
                    }
                    else
                        if (c == stringSep)
                            bolQuote = !bolQuote;
                        else
                            bld.Append(c);
    
                /* to solve the last element problem */
                retAry.Add(bld.ToString()); /* added this line */
                return retAry.ToArray();
            }
    
    0 讨论(0)
  • 2020-11-27 15:52

    If there is only ever one line then do something like this:

    using System;
    using System.IO;
    
    class Program
    {
        static void Main()
        {
            String[] values = File.ReadAllText(@"d:\test.csv").Split(',');
        }
    }
    
    0 讨论(0)
  • 2020-11-27 15:53

    First of all need to understand what is CSV and how to write it.

    (Most of answers (all of them at the moment) do not use this requirements, that's why they all is wrong!)

    1. Every next string ( /r/n ) is next "table" row.
    2. "Table" cells is separated by some delimiter symbol.
    3. As delimiter can be used ANY symbol. Often this is \t or ,.
    4. Each cell possibly can contain this delimiter symbol inside of the cell (cell must to start with double quotes symbol and to have double quote in the end in this case)
    5. Each cell possibly can contains /r/n symbols inside of the cell (cell must to start with double quotes symbol and to have double quote in the end in this case)

    Some time ago I had wrote simple class for CSV read/write based on standard Microsoft.VisualBasic.FileIO library. Using this simple class you will be able to work with CSV like with 2 dimensions array.

    Simple example of using my library:

    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");
    

    You can find my class by the following link and investigate how it's written: https://github.com/ukushu/DataExporter

    This library code is really fast in work and source code is really short.

    PS: In the same time this solution will not work for unity.

    PS2: Another solution is to work with library "LINQ-to-CSV". It must also work well. But it's will be bigger.

    0 讨论(0)
  • 2020-11-27 15:58

    You can try the some thing like the below LINQ snippet.

    string[] allLines = File.ReadAllLines(@"E:\Temp\data.csv");
    
        var query = from line in allLines
                    let data = line.Split(',')
                    select new
                    {
                        Device = data[0],
                        SignalStrength = data[1],
                        Location = data[2], 
                        Time = data[3],
                        Age = Convert.ToInt16(data[4])
                    };
    

    UPDATE: Over a period of time, things evolved. As of now, I would prefer to use this library http://www.aspnetperformance.com/post/LINQ-to-CSV-library.aspx

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