Чтение CSV-файла и сохранение значений в массив - PullRequest
275 голосов
/ 12 марта 2011

Я пытаюсь прочитать *.csv -файл.

Файл *.csv состоит из двух столбцов, разделенных точкой с запятой («; »).

Я могу прочитать *.csv -файл с помощью StreamReader и разделить каждую строку с помощью функции Split(). Я хочу сохранить каждый столбец в отдельный массив, а затем отобразить его.

Возможно ли это сделать?

Ответы [ 18 ]

4 голосов
/ 08 декабря 2015

Вот особый случай, когда одно из полей данных имеет точку с запятой (";") как часть своих данных, в этом случае большинство ответов выше не удастся.

Решение, если этот случай будет

string[] csvRows = System.IO.File.ReadAllLines(FullyQaulifiedFileName);
string[] fields = null;
List<string> lstFields;
string field;
bool quoteStarted = false;
foreach (string csvRow in csvRows)
{
    lstFields = new List<string>();
    field = "";
    for (int i = 0; i < csvRow.Length; i++)
    {
        string tmp = csvRow.ElementAt(i).ToString();
        if(String.Compare(tmp,"\"")==0)
        {
            quoteStarted = !quoteStarted;
        }
        if (String.Compare(tmp, ";") == 0 && !quoteStarted)
        {
            lstFields.Add(field);
            field = "";
        }
        else if (String.Compare(tmp, "\"") != 0)
        {
            field += tmp;
        }
    }
    if(!string.IsNullOrEmpty(field))
    {
        lstFields.Add(field);
        field = "";
    }
// This will hold values for each column for current row under processing
    fields = lstFields.ToArray(); 
}
4 голосов
/ 12 марта 2011
var firstColumn = new List<string>();
var lastColumn = new List<string>();

// your code for reading CSV file

foreach(var line in file)
{
    var array = line.Split(';');
    firstColumn.Add(array[0]);
    lastColumn.Add(array[1]);
}

var firstArray = firstColumn.ToArray();
var lastArray = lastColumn.ToArray();
2 голосов
/ 21 апреля 2016

Библиотека с открытым исходным кодом Angara.Table позволяет загружать CSV в типизированные столбцы, поэтому вы можете получить массивы из столбцов. Каждый столбец может быть проиндексирован как по имени, так и по индексу. Смотри http://predictionmachines.github.io/Angara.Table/saveload.html.

Библиотека следует RFC4180 для CSV; это позволяет вывод типа и многострочные строки.

Пример:

using System.Collections.Immutable;
using Angara.Data;
using Angara.Data.DelimitedFile;

...

ReadSettings settings = new ReadSettings(Delimiter.Semicolon, false, true, null, null);
Table table = Table.Load("data.csv", settings);
ImmutableArray<double> a = table["double-column-name"].Rows.AsReal;

for(int i = 0; i < a.Length; i++)
{
    Console.WriteLine("{0}: {1}", i, a[i]);
}

Вы можете увидеть тип столбца, используя тип Column, например,

Column c = table["double-column-name"];
Console.WriteLine("Column {0} is double: {1}", c.Name, c.Rows.IsRealColumn);

Поскольку библиотека ориентирована на F #, вам может понадобиться добавить ссылку на сборку FSharp.Core 4.4; нажмите «Добавить ссылку» в проекте и выберите FSharp.Core 4.4 в разделе «Сборки» -> «Расширения».

1 голос
/ 03 февраля 2017

Я просто студент, работающий над магистерской диссертацией, но я так решил, и это хорошо сработало.Сначала вы выбираете файл из каталога (только в формате csv), а затем помещаете данные в списки.

List<float> t = new List<float>();
List<float> SensorI = new List<float>();
List<float> SensorII = new List<float>();
List<float> SensorIII = new List<float>();
using (OpenFileDialog dialog = new OpenFileDialog())
{
    try
    {
        dialog.Filter = "csv files (*.csv)|*.csv";
        dialog.Multiselect = false;
        dialog.InitialDirectory = ".";
        dialog.Title = "Select file (only in csv format)";
        if (dialog.ShowDialog() == DialogResult.OK)
        {
            var fs = File.ReadAllLines(dialog.FileName).Select(a => a.Split(';'));
            int counter = 0;
            foreach (var line in fs)
            {
                counter++;
                if (counter > 2)    // Skip first two headder lines
                {
                    this.t.Add(float.Parse(line[0]));
                    this.SensorI.Add(float.Parse(line[1]));
                    this.SensorII.Add(float.Parse(line[2]));
                    this.SensorIII.Add(float.Parse(line[3]));
                }
            }
        }
    }
    catch (Exception exc)
    {
        MessageBox.Show(
            "Error while opening the file.\n" + exc.Message, 
            this.Text, 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error
        );
    }
}
1 голос
/ 04 сентября 2013

Я использую csvreader.com (платный компонент) в течение многих лет, и у меня никогда не было проблем.Он прочный, маленький и быстрый, но за него нужно платить.Вы можете установить разделитель так, как вам нравится.

using (CsvReader reader = new CsvReader(s) {
    reader.Settings.Delimiter = ';';
    reader.ReadHeaders();  // if headers on a line by themselves.  Makes reader.Headers[] available
    while (reader.ReadRecord())
        ... use reader.Values[col_i] ...
}
0 голосов
/ 02 мая 2019

Я потратил несколько часов на поиск подходящей библиотеки, но в конце концов я написал свой собственный код :) Вы можете прочитать файл (или базу данных) любыми инструментами, которые вы хотите, а затем применить следующую процедуру к каждой строке:

private static string[] SmartSplit(string line, char separator = ',')
{
    var inQuotes = false;
    var token = "";
    var lines = new List<string>();
    for (var i = 0; i < line.Length; i++) {
        var ch = line[i];
        if (inQuotes) // process string in quotes, 
        {
            if (ch == '"') {
                if (i<line.Length-1 && line[i + 1] == '"') {
                    i++;
                    token += '"';
                }
                else inQuotes = false;
            } else token += ch;
        } else {
            if (ch == '"') inQuotes = true;
            else if (ch == separator) {
                lines.Add(token);
                token = "";
                } else token += ch;
            }
    }
    lines.Add(token);
    return lines.ToArray();
}
0 голосов
/ 01 апреля 2017

У меня есть библиотека, которая делает именно то, что вам нужно.

Некоторое время назад я написал простую и достаточно быструю библиотеку для работы с CSV-файлами.Вы можете найти его по следующей ссылке: https://github.com/ukushu/DataExporter

Работает с CSV, как с 2-х мерным массивом.Точно так же, как вам нужно.

Например, в случае, если вам нужны все значения 3-й строки, вам нужно всего лишь написать:

Csv csv = new Csv();

csv.FileOpen("c:\\file1.csv");

var allValuesOf3rdRow = csv.Rows[2];

или прочитать 2-ю ячейку

var value = csv.Rows[2][1];
0 голосов
/ 16 июня 2016

Все еще не так. Вам нужно компенсировать "" в кавычках. Вот мое решение Microsoft стиль CSV.

               /// <summary>
    /// Microsoft style csv file.  " is the quote character, "" is an escaped quote.
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="sepChar"></param>
    /// <param name="quoteChar"></param>
    /// <param name="escChar"></param>
    /// <returns></returns>
    public static List<string[]> ReadCSVFileMSStyle(string fileName, char sepChar = ',', char quoteChar = '"')
    {
        List<string[]> ret = new List<string[]>();

        string[] csvRows = System.IO.File.ReadAllLines(fileName);

        foreach (string csvRow in csvRows)
        {
            bool inQuotes = false;
            List<string> fields = new List<string>();
            string field = "";
            for (int i = 0; i < csvRow.Length; i++)
            {
                if (inQuotes)
                {
                    // Is it a "" inside quoted area? (escaped litteral quote)
                    if(i < csvRow.Length - 1 && csvRow[i] == quoteChar && csvRow[i+1] == quoteChar)
                    {
                        i++;
                        field += quoteChar;
                    }
                    else if(csvRow[i] == quoteChar)
                    {
                        inQuotes = false;
                    }
                    else
                    {
                        field += csvRow[i];
                    }
                }
                else // Not in quoted region
                {
                     if (csvRow[i] == quoteChar)
                    {
                        inQuotes = true;
                    }
                    if (csvRow[i] == sepChar)
                    {
                        fields.Add(field);
                        field = "";
                    }
                    else 
                    {
                        field += csvRow[i];
                    }
                }
            }
            if (!string.IsNullOrEmpty(field))
            {
                fields.Add(field);
                field = "";
            }
            ret.Add(fields.ToArray());
        }

        return ret;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...