Laden...

CSV einlesen ab bestimmter Zeile

Erstellt von dila71 vor 5 Jahren Letzter Beitrag vor 5 Jahren 2.837 Views
D
dila71 Themenstarter:in
103 Beiträge seit 2005
vor 5 Jahren
CSV einlesen ab bestimmter Zeile

Hallo,
nach einiger Googelei habe ich einige Bibliotheken zum Thema CSV einlesen gefunden.

Bei allen kann man eigentlich sagen, Header true/false.

Nun habe ich aber eine Datei in folgendem Aufbau (gegeben ich kann es nicht beeinflussen)


Datensatzbezeichnung
Datum;Zeit;Wert
01.01.2018;20:15;678
02.01.2018;17:54;478
.....

Kennt Jemand ein Framework bei dem ich angeben kann:
Das ist die Quelle (ok, das können alle)
lies (nur) Zeile 1 in Variable x und lies ab Zeile 3 Objekte in Variable y

oder eben lies mit Header ab Zeile 2.

Im Notfall kann ich es auch selber programmieren, aber dry, warum etwas coden wenn es schon ein Framework gibt

Viele Dank
Diek

T
2.224 Beiträge seit 2008
vor 5 Jahren

Meines Wissens nach, ist sowas bei CSV nicht üblich.
Wüsste auch nicht, dass es ein Framework gibt, was solch einen Fall beachtet.

Aber bei der einfachen Struktur, könntest du die Datei schneller mit Bordmitteln von .NET einlesen, also auf eine Antwort zu warten bzw. eine entsprechende Lösung zu suchen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

4.939 Beiträge seit 2008
vor 5 Jahren

Kannst du nicht einen Stream bei den Bibliotheken benutzen, so daß du dann einfach selber vorher die erste Zeile (oder gleich 2 Zeilen) überliest.

C
224 Beiträge seit 2009
vor 5 Jahren

        void ReadMyFile()
        {
            //Datei lesen
            string[] fileLines = System.IO.File.ReadAllLines(@"C:\test\MeineDaten.csv");

            //Datei parsen
            List<Record> records;
            {
                const int HEADERS = 2;
                if (fileLines.Length <= HEADERS) throw new ArgumentException("Keine Daten");

                records = new List<Record>();
                for (int i = HEADERS; i < fileLines.Length; i++)
                {
                    records.Add(ParseRecord(fileLines[i]));
                }
            }

            //Ausgabe:
            {
                StringBuilder sb = new StringBuilder();
                foreach (var record in records)
                {
                    sb.AppendLine(record.timestamp.ToString("dd.MM.yyyy HH:mm") + " | " + record.text);
                }
                MessageBox.Show(sb.ToString());
            }
        }

        class Record
        {
            public DateTime timestamp { get; set; }
            public string text { get; set; }
        }

        static Record ParseRecord(string line)
        {
            const int COLUMNS = 3;

            if (string.IsNullOrEmpty(line)) throw new ArgumentException("No data");

            string[] tupel = line.Split(';');
            if (tupel.Length != COLUMNS) throw new ArgumentException("Invalid column quantity");

            Record record = new Record();
            {
                const string DATE_FORMAT = "dd.MM.yyyy";
                const string TIME_FORMAT = "HH:mm";
                record.timestamp = DateTime.ParseExact
                (
                    tupel[0] + tupel[1],
                    DATE_FORMAT + TIME_FORMAT,
                    System.Globalization.CultureInfo.InvariantCulture
                );
                record.text = tupel[2];
            }
            return record;
        }

2.079 Beiträge seit 2012
vor 5 Jahren

Der CsvReader von CsvHelper bekommt einen TextReader, von dem unter Anderem der StreamReader ableitet.

Ich würde daher einfach das testen und vor dem Parsen der CSV mit dem StreamReader eine Zeile lesen, sodass der CSVReader dann bei der zweiten Zeile beginnt.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

C
2.121 Beiträge seit 2010
vor 5 Jahren

warum etwas coden wenn es schon ein Framework gibt

Natürlich sollte man nicht alles selbst machen, nur damit es selbst gemacht ist.
Allerdings sieht das CSV sehr simpel aus. Wenn es wirklich so ist wie ich denke, würde die Antwort lauten:
Weil man nicht für jeden Schnipsel Code ein Framework braucht.
Weil du, wie man in einem vorigen Beitrag sieht, wahrscheinlich bereits ein Vielfaches länger gesucht hast als das selbst Coden benötigt hätte.
Weil das was du gefunden hast nicht das kann was du brauchst.

16.833 Beiträge seit 2008
vor 5 Jahren

Ich sehe das wie T-Virus; prinzipiell ist das einfach eine ungültige CSV.
Einen Datensatz-Titel ist hier nicht vorgesehen.

Ich würde aber nicht einen offenen Stream manipulieren und die erste Zeile überspringen; sondern ich würde hier einen neuen Stream erstellen, in dem nur die gültigen CSV Inhalte landen und diese an eine bereits getestete und existiertende CSV Bibliothek übergeben.

Das alles selbst zu machen, chilic, mag zwar auf den ersten Blick einfach sein.
Aber es gehört einfach auf getestet - und am Ende erfindest dann doch das Rad neu.

Aber mit dem First Line Skip eine vorhandene, gültige CSV Bibliothek zu nehmen: dem steht ja nichts im Weg.

T
2.224 Beiträge seit 2008
vor 5 Jahren

@Abt
Stimme ich dir zu.
Kann dann auch bei korrekter Umsetzung, für weitere Fälle dieser Art dann auch wiederverwendet werden, was bei einer eigenen Lösung wieder nur mit Copy/Paste oder eben durch eine Skip Methode möglich wäre.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

2.079 Beiträge seit 2012
vor 5 Jahren

Noch ein Problem mit selbstgebastelten Lösungen:

Ich habe hier jeden Tag mit einer Software zu tun, wo es an jeder Ecke solche Eigenentwicklungen gibt, weil das eben schneller war, als 10 Minuten mehr zum Doku-Lesen zu investieren.
Nun bin ich mehr und mehr damit beschäftigt, eben diese Eigenentwicklungen mit teils geringem, aber auch teils großem Aufwand durch bereits etablierte Frameworks zu ersetzen, weil es neue Anforderungen gibt, welche die Eigenentwicklung einfach nicht unterstützt.

Oder anders formuliert:
Sobald Du etwas selber baust, mag das am Anfang zwar schön schnell und einfach klingen, aber es wird mit an Sicherheit grenzenden Wahrscheinlichkeit Anforderungen geben, die eine Anpassung an diesem selbst gebauten Zeug fordern.
Vorhandene Frameworks sind oft dafür gebaut, flexibel zu agieren und offen für Veränderungen zu funktionieren - oder sie unterstützen die geforderten Funktionen schon out of the box.

Langfristig betrachtet sparst Du also keine Zeit, wahrscheinlicher ist, dass Du Zeit verlierst.
Und das betrifft jetzt nicht einmal den zusätzlichen Aufwand für eine anständige Test-Abdeckung, die bei etablierten Frameworks schon "inklusive" ist.

Abgesehen davon lernst Du mit der Zeit immer mehr und mehr Frameworks kennen, viele davon sind insofern ähnlich aufgebaut, dass häufig die Intellisense-Hilfe ausreicht um das Framework erfolgreich einzusetzen. Mit der Zeit fällt also nicht Mal mehr Einarbeitungszeit an, sondern man installiert nur schnell das Package und fünf Minuten später ist das Feature fertig.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

D
dila71 Themenstarter:in
103 Beiträge seit 2005
vor 5 Jahren

DANKE, DANKE, DANKE

Gerade das "ein Framework ist getestet" Thema ist eben das, warum ich, auch für ein Konstrukt welches man auch einfach mit:


using (StreamReader sr = new StreamReader("..."))
{
    int ignoreLines = 2;
    int lineCounter = 0;

    string line;

    while ((line = sr.ReadLine()) != null)
    {
        lineCounter++;
        if (lineCounter > ignoreLines)
        {
....

lösen kann, nach einem Framework gesucht habe.

Danke an alle

Dirk