444 Stimmen

CSV-Datei lesen und Werte in einem Array speichern

Ich versuche, eine *.csv -Datei.

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

Ich bin in der Lage, die *.csv -Datei mit StreamReader und der Möglichkeit, jede Zeile mit dem Split() Funktion. Ich möchte jede Spalte in einem separaten Array speichern und dann anzeigen.

Ist das möglich?

6voto

Mathias Schmidt Punkte 61

Hallo zusammen, ich habe eine statische Klasse für diese Aufgabe erstellt. + Spaltenprüfung + Entfernung von Quotenzeichen

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

}

5voto

Jakub Konecki Punkte 44858
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();

4voto

Yogesh Punkte 1515

Hier ist ein spezieller Fall, in dem eines der Datenfelder ein Semikolon (";") als Teil der Daten enthält. In diesem Fall werden die meisten der obigen Antworten fehlschlagen.

Die Lösung lautet in diesem 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(); 
}

3voto

Die Open-Source Angara.Tabelle Bibliothek erlaubt es, CSV in typisierte Spalten zu laden, so dass Sie die Arrays aus den Spalten erhalten 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; sie ermöglicht Typinferenz und mehrzeilige Strings.

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 Column anzeigen, z. B.

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

Da die Bibliothek auf F# ausgerichtet ist, müssen Sie möglicherweise einen Verweis auf die FSharp.Core 4.4-Assembly hinzufügen; klicken Sie im Projekt auf "Verweis hinzufügen" und wählen Sie FSharp.Core 4.4 unter "Assemblies" -> "Extensions".

2voto

Oliver Bock Punkte 4493

Ich verwende csvreader.com (kostenpflichtige Komponente) schon seit Jahren und hatte noch nie ein Problem. Es ist solide, klein und schnell, aber man muss dafür bezahlen. Sie können das Trennzeichen einstellen, wie Sie wollen.

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] ...
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X