CSV-Datei lesen und Werte in einem Array speichern

317

Ich versuche eine *.csvDatei zu lesen .

Die *.csv-Datei besteht aus zwei durch Semikolon (" ; ") getrennten Spalten .

Ich kann die *.csvDatei mit StreamReader lesen und jede Zeile mithilfe der Split()Funktion trennen . Ich möchte jede Spalte in einem separaten Array speichern und dann anzeigen.

Ist das möglich?

Rushabh Shah
quelle
2
@Marc: Leider in nicht-englischen Kulturen (zB Italienisch), wenn Sie ein Excel in CSV speichern, das es ";"als Trennzeichen verwendet ... dies hat CSV zu einem nicht standardmäßigen Imo gemacht :(
digEmAll
25
Ich lese CSV immer als durch Zeichen getrennte Werte, da Leute Dateien als CSV bezeichnen, auch wenn sie kein Komma als Trennzeichen verwenden. Und es gibt in der Praxis so viele Dialekte mit unterschiedlichen Zitier- oder Fluchtregeln, dass man nicht wirklich von einem Standard sprechen kann, selbst wenn es theoretisch einen RFC gibt.
CodesInChaos
1
Der Name der CSV-Dateierweiterung sollte jetzt in DSV - Delimiter Separated Values File
Ambuj,
Für alle Antworten, bei denen die Zeichenfolge des Trennzeichens einfach aufgeteilt wird, ist dies nicht der beste Weg. Das CSV-Format enthält weitere Regeln, die hier nicht behandelt werden. Verwenden Sie am besten einen Parser eines Drittanbieters. Weitere Info- dotnetcoretutorials.com/2018/08/04/csv-parsing-in-net-core
iliketocode

Antworten:

415

Sie können es so machen:

using System.IO;

static void Main(string[] args)
{
    using(var reader = new StreamReader(@"C:\test.csv"))
    {
        List<string> listA = new List<string>();
        List<string> listB = new List<string>();
        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            var values = line.Split(';');

            listA.Add(values[0]);
            listB.Add(values[1]);
        }
    }
}
Michael M.
quelle
5
Vielen Dank dafür, ich hatte vergessen, wie man Zeilen in einer CSV-Datei teilt (dumm mich!), Aber Ihre Lösung half mir :)
Hallaghan
4
Es ist über 3 Jahre später und diese Frage hilft immer noch jemandem. Ich fühle mich schlecht, dass Sie dies nicht akzeptiert haben.
AdamMc331
12
Behandelt keine Feldwerte mit Kommas usw.
Mike
12
Sollte usinghier eine Klausel verwenden, oder zumindest manuell Close()die, readerda es sich um eine IDisposibleRessource handelt.
Assaf Israel
30
Dies wird auch eine CSV nicht richtig analysieren, die wie column1;"Special ; char in string";column3- tools.ietf.org/html/rfc4180
Ole K
173

Mein Lieblings-CSV-Parser ist ein in die .NET-Bibliothek integrierter. Dies ist ein versteckter Schatz im Microsoft.VisualBasic-Namespace. Unten finden Sie einen Beispielcode:

using Microsoft.VisualBasic.FileIO;

var path = @"C:\Person.csv"; // Habeeb, "Dubai Media City, Dubai"
using (TextFieldParser csvParser = new TextFieldParser(path))
{
 csvParser.CommentTokens = new string[] { "#" };
 csvParser.SetDelimiters(new string[] { "," });
 csvParser.HasFieldsEnclosedInQuotes = true;

 // Skip the row with the column names
 csvParser.ReadLine();

 while (!csvParser.EndOfData)
 {
  // Read current line fields, pointer moves to the next line.
  string[] fields = csvParser.ReadFields();
  string Name = fields[0];
  string Address = fields[1];
 }
}

Denken Sie daran, einen Verweis auf hinzuzufügen Microsoft.VisualBasic

Weitere Details zum Parser finden Sie hier: http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html

Habeeb
quelle
6
Ich mag diese Option am besten. Ich muss mich nicht um Escape-Zeichen kümmern, da die Klasse ein CSV-Parser ist und nicht manuell erstellt wird.
Timothy Gonzalez
22
Falls jemand darauf stößt und sich wundert, müssen Sie den Verweis auf die Microsoft.VisualBasicFramework-Assembly einfügen, da normalerweise nicht standardmäßig darauf verwiesen wird.
Apokryfos
3
Ich wünschte, ich hätte mich aus meinen VB6-Tagen daran erinnert und mir über die Jahre viel Zeit gespart. Während einige über VB schimpfen, habe ich kein Problem damit, die DLL und den Namespace zu meinem Code hinzuzufügen, wenn er einen Wert hat. Dies hat viel Wert.
Walter
2
Diese Lösung ist ein Homerun. sehr zuverlässiger Parser aus meiner Erfahrung.
Glenn Ferrie
3
Warum nur in VB DLL?
Mark Choi
75

LINQ Weg:

var lines = File.ReadAllLines("test.txt").Select(a => a.Split(';'));
var csv = from line in lines
          select (from piece in line
                  select piece);

^^ Falsch - Bearbeiten von Nick

Es scheint, dass der ursprüngliche Antwortende versucht hat, csvmit einem zweidimensionalen Array zu füllen - einem Array, das Arrays enthält. Jedes Element im ersten Array enthält ein Array, das diese Zeilennummer darstellt, wobei jedes Element im verschachtelten Array die Daten für diese bestimmte Spalte enthält.

var csv = from line in lines
          select (line.Split(',')).ToArray();
ASCII
quelle
2
Vielleicht fehlt mir etwas, aber ich bin mir nicht sicher, wozu Ihre CSV-Variable gut ist - erstellen Sie nicht einfach dieselbe Datenstruktur neu, die bereits in Zeilen vorhanden ist?
Ben Hughes
13
@ClayShannon .NET 1.1? Es tut mir ... sehr leid für dich.
Kontaktmatt
5
@contactmatt: Ich werde dich nicht von diesem Gefühl abbringen.
B. Clay Shannon
9
Ich möchte auch darauf hinweisen, dass CSVs in Anführungszeichen gesetzt werden können ... Die Verwendung von string.Split ist also keine praktikable Option.
Alxandr
5
Ich erhalte folgende Meldung: 'System.Array' enthält keine Definition für 'Split' und es konnte keine Erweiterungsmethode 'Split' gefunden werden, die ein erstes Argument vom Typ 'System.Array' akzeptiert (fehlt Ihnen eine using-Direktive oder eine Assemblyreferenz) ?)
Kala J
36

Sie können ein Array nicht sofort erstellen, da Sie die Anzahl der Zeilen von Anfang an kennen müssen (und dies würde das zweimalige Lesen der CSV-Datei erfordern).

Sie können Werte in zwei speichern List<T>und dann verwenden oder mithilfe von in ein Array konvertierenList<T>.ToArray()

Sehr einfaches Beispiel:

var column1 = new List<string>();
var column2 = new List<string>();
using (var rd = new StreamReader("filename.csv"))
{
    while (!rd.EndOfStream)
    {
        var splits = rd.ReadLine().Split(';');
        column1.Add(splits[0]);
        column2.Add(splits[1]);
    }
}
// print column1
Console.WriteLine("Column 1:");
foreach (var element in column1)
    Console.WriteLine(element);

// print column2
Console.WriteLine("Column 2:");
foreach (var element in column2)
    Console.WriteLine(element);

NB

Bitte beachten Sie, dass dies nur ein sehr einfaches Beispiel ist . Die Verwendung string.Splitberücksichtigt keine Fälle, in denen einige Datensätze das Trennzeichen enthalten ;.
Für einen sichereren Ansatz sollten Sie einige CSV-spezifische Bibliotheken wie CsvHelper auf Nuget verwenden.

digEmAll
quelle
Berücksichtigt ;beispielsweise nicht, dass es Teil des Werts ist "value with ; inside it". CSV-Surround-Werte, die Sonderzeichen mit doppelten Anführungszeichen enthalten, um zu sagen, dass es sich um eine Literalzeichenfolge handelt.
ChickenFeet
1
@ChickenFeet: Sicher, das ist der Grund für die Überschrift: "Sehr einfaches Beispiel" . Wie auch immer, ich kann eine Notiz dazu hinzufügen;)
digEmAll
Keine Sorge, ich habe bemerkt, dass viele andere Antworten hier auch nicht berücksichtigt werden :)
ChickenFeet
1
Regex.Split (sr.ReadLine (), ", (? = (?: [^ \"] * \ "[^ \"] * \ ") * [^ \"] * $) "); // Gefunden dies auf SO ... schneller als eine Bibliothek.
Pinch
34

Ich bin gerade auf diese Bibliothek gestoßen : https://github.com/JoshClose/CsvHelper

Sehr intuitiv und einfach zu bedienen. Hat auch ein Nuget-Paket, das schnell implementiert werden kann: http://nuget.org/packages/CsvHelper/1.17.0 . Scheint auch aktiv gepflegt zu werden was mir gefällt.

Die Konfiguration für die Verwendung eines Semikolons ist einfach: https://github.com/JoshClose/CsvHelper/wiki/Custom-Configurations

Joshb
quelle
3
Das ist die beste Antwort! Robuste Bibliothek, mit der Sie einfach einsteigen und loslegen können.
Tyler Forsythe
3
Die CsvHelper-Bibliothek ist fantastisch. Super schnell und einfach zu bedienen.
Steve Parish
3
Wenn Sie nach einer Bibliothek suchen, die alle Aspekte des CSV-Formats einschließlich der Zeichenfolgen in Anführungszeichen abdeckt, verwenden Sie diese. Genial!
Matt
Danke, wirklich schöne Bibliothek, einfach zu bedienen und sehr robust.
Sebastián Guerrero
2
Wie ist die Leistung im Vergleich zu Microsoft.VisualBasic.FileIO.TextFieldParser(vgl. Antwort von @ Habeeb)?
Bovender
33

Normalerweise verwende ich diesen Parser aus Codeproject , da es eine Reihe von Zeichen- Escapezeichen und Ähnlichem gibt, die für mich behandelt werden.

Paul
quelle
2
Dieses Ding ist sehr gut und schnell. Wenn Sie sich in einer geschäftlichen Situation befinden und Cracking benötigen, verwenden Sie diese Option.
Gjvdkamp
8
Dieser Parser ist in der Nuget-Galerie als LumenWorks.Framework.IO verfügbar, falls Sie sich nicht für CodeProject registrieren möchten, um ihn herunterzuladen.
Greg McCoy
30

Hier ist meine Variation der am besten bewerteten Antwort:

var contents = File.ReadAllText(filename).Split('\n');
var csv = from line in contents
          select line.Split(',').ToArray();

Die csvVariable kann dann wie im folgenden Beispiel verwendet werden:

int headerRows = 5;
foreach (var row in csv.Skip(headerRows)
    .TakeWhile(r => r.Length > 1 && r.Last().Trim().Length > 0))
{
    String zerothColumnValue = row[0]; // leftmost column
    var firstColumnValue = row[1];
}
tomsv
quelle
Wie greifen Sie auf die Zeilen und Spalten in der CSV-Variablen zu?
Matthew Lock
1
Wie gehst du mit Escape-Komma um?
Kuangwei Zhang
Behandelt keine Kommas in Spalten. Verwenden Sie besser die robuste Bibliothek CsvHelper gemäß der Antwort von
Tim Partridge
11

Wenn Sie (Kopf-) Zeilen und / oder Spalten überspringen müssen, können Sie damit ein zweidimensionales Array erstellen:

    var lines = File.ReadAllLines(path).Select(a => a.Split(';'));
    var csv = (from line in lines               
               select (from col in line
               select col).Skip(1).ToArray() // skip the first column
              ).Skip(2).ToArray(); // skip 2 headlines

Dies ist sehr nützlich, wenn Sie die Daten formen müssen, bevor Sie sie weiterverarbeiten (vorausgesetzt, die ersten beiden Zeilen bestehen aus der Überschrift, und die erste Spalte ist ein Zeilentitel - den Sie nicht im Array haben müssen, weil Sie nur die Daten betrachten wollen).

Hinweis : Mit dem folgenden Code können Sie die Überschriften und die erste Spalte leicht abrufen:

    var coltitle = (from line in lines 
                    select line.Skip(1).ToArray() // skip 1st column
                   ).Skip(1).Take(1).FirstOrDefault().ToArray(); // take the 2nd row
    var rowtitle = (from line in lines select line[0] // take 1st column
                   ).Skip(2).ToArray(); // skip 2 headlines

Dieses Codebeispiel nimmt die folgende Struktur Ihrer *.csvDatei an:

CSV-Matrix

Hinweis: Wenn Sie leere Zeilen überspringen müssen - was manchmal praktisch ist, können Sie dies durch Einfügen tun

    where line.Any(a=>!string.IsNullOrWhiteSpace(a))

zwischen der fromund der selectAnweisung in den obigen LINQ- Codebeispielen.

Matt
quelle
10

Sie können die DLL Microsoft.VisualBasic.FileIO.TextFieldParser in C # verwenden, um eine bessere Leistung zu erzielen

Holen Sie sich das folgende Codebeispiel aus dem obigen Artikel

static void Main()
{
    string csv_file_path=@"C:\Users\Administrator\Desktop\test.csv";

    DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);

    Console.WriteLine("Rows count:" + csvData.Rows.Count);

    Console.ReadLine();
}


private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
    DataTable csvData = new DataTable();

    try
    {

    using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
        {
            csvReader.SetDelimiters(new string[] { "," });
            csvReader.HasFieldsEnclosedInQuotes = true;
            string[] colFields = csvReader.ReadFields();
            foreach (string column in colFields)
            {
                DataColumn datecolumn = new DataColumn(column);
                datecolumn.AllowDBNull = true;
                csvData.Columns.Add(datecolumn);
            }

            while (!csvReader.EndOfData)
            {
                string[] fieldData = csvReader.ReadFields();
                //Making empty value as null
                for (int i = 0; i < fieldData.Length; i++)
                {
                    if (fieldData[i] == "")
                    {
                        fieldData[i] = null;
                    }
                }
                csvData.Rows.Add(fieldData);
            }
        }
    }
    catch (Exception ex)
    {
    }
    return csvData;
}
kombsh
quelle
9
Es ist nicht so effizient, weil Split nicht alles macht, was TextFieldParser macht. Überspringen Sie beispielsweise Kommentarzeilen, behandeln Sie Felder in Anführungszeichen und entfernen Sie beginnende / nachfolgende Leerzeichen. Nicht gerade ein 1: 1 Vergleich.
Robert McKee
5

Hallo zusammen, ich habe dafür eine statische Klasse erstellt. + Spaltenprüfung + Entfernen von Kontingentzeichen

public static class CSV
{
    public static List<string[]> Import(string file, char csvDelimiter, bool ignoreHeadline, bool removeQuoteSign)
    {
        return ReadCSVFile(file, csvDelimiter, ignoreHeadline, removeQuoteSign);
    }

    private static List<string[]> ReadCSVFile(string filename, char csvDelimiter, bool ignoreHeadline, bool removeQuoteSign)
    {
        string[] result = new string[0];
        List<string[]> lst = new List<string[]>();

        string line;
        int currentLineNumner = 0;
        int columnCount = 0;

        // Read the file and display it line by line.  
        using (System.IO.StreamReader file = new System.IO.StreamReader(filename))
        {
            while ((line = file.ReadLine()) != null)
            {
                currentLineNumner++;
                string[] strAr = line.Split(csvDelimiter);
                // save column count of dirst line
                if (currentLineNumner == 1)
                {
                    columnCount = strAr.Count();
                }
                else
                {
                    //Check column count of every other lines
                    if (strAr.Count() != columnCount)
                    {
                        throw new Exception(string.Format("CSV Import Exception: Wrong column count in line {0}", currentLineNumner));
                    }
                }

                if (removeQuoteSign) strAr = RemoveQouteSign(strAr);

                if (ignoreHeadline)
                {
                    if(currentLineNumner !=1) lst.Add(strAr);
                }
                else
                {
                    lst.Add(strAr);
                }
            }

        }

        return lst;
    }
    private static string[] RemoveQouteSign(string[] ar)
    {
        for (int i = 0;i< ar.Count() ; i++)
        {
            if (ar[i].StartsWith("\"") || ar[i].StartsWith("'")) ar[i] = ar[i].Substring(1);
            if (ar[i].EndsWith("\"") || ar[i].EndsWith("'")) ar[i] = ar[i].Substring(0,ar[i].Length-1);

        }
        return ar;
    }

}
Mathias Schmidt
quelle
4
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();
Jakub Konecki
quelle
Danke für Ihre Hilfe. Es könnte helfen, mein Problem zu lösen. Eigentlich muss ich Daten aus der Datei lesen und dann in die Datenbank einfügen. Zum Zeitpunkt des Einfügens wird ein Primärschlüsseleinschränkungsfehler angezeigt (da ich bereits Daten in der Datenbank habe). Also muss ich so programmieren, dass mit bereits vorhandener Variable die Daten aktualisiert werden.
Rushabh Shah
Ich nehme den ersten Wert an, wenn PK - Sie müssen einen Datensatz anhand der ID aus der Datenbank abrufen, und wenn er vorhanden ist, geben Sie eine UPDATE-Anweisung aus, andernfalls fügen Sie einen neuen Datensatz ein.
Jakub Konecki
3

Hier ist ein Sonderfall, in dem eines der Datenfelder ein Semikolon (";") als Teil seiner Daten enthält. In diesem Fall schlagen die meisten der oben genannten Antworten fehl.

Lösung ist der Fall

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(); 
}
Yogesh
quelle
2

Die Open-Source- Bibliothek Angara.Table ermöglicht das Laden von CSV in typisierte Spalten, sodass Sie die Arrays aus den Spalten abrufen können. Jede Spalte kann sowohl nach Namen als auch nach Index indiziert werden. Siehe http://predictionmachines.github.io/Angara.Table/saveload.html .

Die Bibliothek folgt RFC4180 für CSV; Es ermöglicht Typinferenz und mehrzeilige Zeichenfolgen.

Beispiel:

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

Sie können einen Spaltentyp mit dem Typ Spalte anzeigen, z

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

Da sich die Bibliothek auf F # konzentriert, müssen Sie möglicherweise einen Verweis auf die FSharp.Core 4.4-Assembly hinzufügen. Klicken Sie im Projekt auf "Referenz hinzufügen" und wählen Sie "FSharp.Core 4.4" unter "Baugruppen" -> "Erweiterungen".

Dmitry Voytsekhovskiy
quelle
2

Ich habe einige Stunden damit verbracht, nach einer richtigen Bibliothek zu suchen, aber schließlich habe ich meinen eigenen Code geschrieben :) Sie können Dateien (oder Datenbanken) mit beliebigen Tools lesen und dann die folgende Routine auf jede Zeile anwenden:

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();
}
Zbyszek Swirski
quelle
1

Ich benutze csvreader.com (kostenpflichtige Komponente) seit Jahren und hatte nie ein Problem. Es ist solide, klein und schnell, aber Sie müssen dafür bezahlen. Sie können das Trennzeichen auf einen beliebigen Wert einstellen.

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] ...
}
Oliver Bock
quelle
1

Ich bin nur ein Student, der an meiner Masterarbeit arbeitet, aber so habe ich es gelöst und es hat gut für mich funktioniert. Zuerst wählen Sie Ihre Datei aus dem Verzeichnis aus (nur im CSV-Format) und fügen dann die Daten in die Listen ein.

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
        );
    }
}
Daniel
quelle
0

Immer noch falsch. Sie müssen "" in Anführungszeichen kompensieren. Hier ist meine Lösung Microsoft Style 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;
    }
}
R Keene
quelle
3
Es behandelt den Fall nicht, wenn es Zeilenumbrüche innerhalb der Spaltenwerte gibt;)
Emil
0

Ich habe eine Bibliothek, die genau das tut, was Sie brauchen.

Vor einiger Zeit hatte ich eine einfache und schnelle Bibliothek für die Arbeit mit CSV-Dateien geschrieben. Sie finden es unter folgendem Link: https://github.com/ukushu/DataExporter

Es funktioniert mit CSV wie mit einem 2-Dimensionen-Array. Genau so, wie Sie es brauchen.

Wenn Sie beispielsweise alle Werte der 3. Zeile benötigen, müssen Sie nur Folgendes schreiben:

Csv csv = new Csv();

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

var allValuesOf3rdRow = csv.Rows[2];

oder 2. Zelle von zu lesen

var value = csv.Rows[2][1];
Andrew
quelle
-1

Schau dir das an

Verwenden von CsvFramework;

using System.Collections.Generic;

Namespace CvsParser {

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Order> Orders { get; set; }        
}

public class Order
{
    public int Id { get; set; }

    public int CustomerId { get; set; }
    public int Quantity { get; set; }

    public int Amount { get; set; }

    public List<OrderItem> OrderItems { get; set; }

}

public class Address
{
    public int Id { get; set; }
    public int CustomerId { get; set; }

    public string Name { get; set; }
}

public class OrderItem
{
    public int Id { get; set; }
    public int OrderId { get; set; }

    public string ProductName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {

        var customerLines = System.IO.File.ReadAllLines(@"Customers.csv");
        var orderLines = System.IO.File.ReadAllLines(@"Orders.csv");
        var orderItemLines = System.IO.File.ReadAllLines(@"OrderItemLines.csv");

        CsvFactory.Register<Customer>(builder =>
        {
            builder.Add(a => a.Id).Type(typeof(int)).Index(0).IsKey(true);
            builder.Add(a => a.Name).Type(typeof(string)).Index(1);
            builder.AddNavigation(n => n.Orders).RelationKey<Order, int>(k => k.CustomerId);

        }, false, ',', customerLines);

        CsvFactory.Register<Order>(builder =>
        {
            builder.Add(a => a.Id).Type(typeof(int)).Index(0).IsKey(true);
            builder.Add(a => a.CustomerId).Type(typeof(int)).Index(1);
            builder.Add(a => a.Quantity).Type(typeof(int)).Index(2);
            builder.Add(a => a.Amount).Type(typeof(int)).Index(3);
            builder.AddNavigation(n => n.OrderItems).RelationKey<OrderItem, int>(k => k.OrderId);

        }, true, ',', orderLines);


        CsvFactory.Register<OrderItem>(builder =>
        {
            builder.Add(a => a.Id).Type(typeof(int)).Index(0).IsKey(true);
            builder.Add(a => a.OrderId).Type(typeof(int)).Index(1);
            builder.Add(a => a.ProductName).Type(typeof(string)).Index(2);


        }, false, ',', orderItemLines);



        var customers = CsvFactory.Parse<Customer>();


    }
}

}}

Tobias
quelle