it-swarm.com.ru

Очень простой читатель C # CSV

Я хотел бы создать массив из файла CSV.

Это так просто, как вы можете себе представить, файл CSV будет иметь только одну строку и следующие значения:

Device, SignalStrength, Location, Time, Age.

Я хотел бы поместить эти значения в одномерный массив.

Я попробовал несколько примеров, но все они были более сложными, чем требовалось.

37
DNN

Если есть только одна строка, сделайте что-то вроде этого:

using System;
using System.IO;

class Program
{
    static void Main()
    {
        String[] values = File.ReadAllText(@"d:\test.csv").Split(',');
    }
}
51
Andrew Hare

Вы можете попробовать что-то вроде приведенного ниже фрагмента LINQ.

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])
                };

ОБНОВЛЕНИЕ: В течение некоторого времени все развивалось. На данный момент я бы предпочел использовать эту библиотеку http://www.aspnetperformance.com/post/LINQ-to-CSV-library.aspx

64
Ramesh

Вот простая функция, которую я сделал. Он принимает строку CSV и возвращает массив полей:

Он хорошо работает с CSV-файлами, созданными в Excel, и многими другими вариантами.

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

    }
8
Chris Wilson

Эта фиксированная версия кода выше запоминает последний элемент строки CVS ;-)

(протестировано с файлом CSV с 5400 строками и 26 элементами по строкам)

   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();
        }
4
Paolo D.a

Это то, что я использовал в проекте, анализирует одну строку данных.

    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

3
Zamir

Мое решение обрабатывает кавычки, переопределяет поля и разделители строк и т.д. Оно короткое и приятное.

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

        return retAry.ToArray();
    }
2
A. Richard Temps

Прежде всего необходимо понять, что такое CSV и как его написать.

(Большинство ответов (все они на данный момент) не используют эти требования, поэтому все они ошибаются!)

  1. Каждая следующая строка (/r/n) следующая строка "таблицы".
  2. Ячейки таблицы разделены каким-либо символом-разделителем.
  3. В качестве разделителя можно использовать ЛЮБОЙ символ. Часто это \t или ,.
  4. Возможно, каждая ячейка может содержать этот символ разделителя внутри ячейки (ячейка должна начинаться с символа двойных кавычек и иметь двойную кавычку в конце в этом случае)
  5. Каждая ячейка может содержать /r/n символы внутри ячейки (ячейка должна начинаться с символа двойных кавычек и в этом случае иметь двойные кавычки)

Некоторое время назад я написал простой класс для чтения/записи CSV, основанный на стандарте Microsoft.VisualBasic.FileIO библиотека. Используя этот простой класс, вы сможете работать с CSV, как с 2-х мерным массивом.

Простой пример использования моей библиотеки:

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

Вы можете найти мой класс по следующей ссылке и узнать, как он написан: https://github.com/ukushu/DataExporter

Этот код библиотеки действительно быстр в работе, а исходный код очень короткий.

PS: В то же время это решение не будет работать на единство.

PS2: еще одно решение - работа с библиотекой "LINQ-to-CSV". Это также должно работать хорошо. Но это будет больше.

0
Andrew