Csvhelper: Zählen bekommen

Erstellt am 12. März 2018  ·  5Kommentare  ·  Quelle: JoshClose/CsvHelper

Ich habe ein ähnliches Problem mit #92. Aber ich bin mir nicht sicher, ob ich das über 5 Jahre alte Problem hätte anstoßen sollen, also erstelle ich ein neues.

Mir ist bewusst, dass das Aufrufen von Count() für die aufgezählten Datensätze dazu führt, dass der Cursor ans Ende geht und die weitere Operation / foreach Schleife für die Datensätze nichts zurückgibt.

Die Gliederung meines Codes ist wie folgt

````C#
var myCSV = new CsvReader(File.OpenText(txtBox_CSVFile.Text));
myCSV.Configuration.RegisterClassMap();

var record = new MyRecordClass();
var allRecords = myCSV.EnumerateRecords(record);
int recordsLength = allRecords.Count<MyRecordClass>();

foreach (var r in allRecords)
{
    /* some read/write operation here
    */
    scannedCSVEntry++;
    progress.value = scannedCSVEntry/recordsLength;
}

````

Das recordsLength ist hier wichtig, da ich den Fortschrittsbalken aktualisieren muss, während ich den Eintrag verarbeite

Aber wie kann ich das umgehen?

Hilfreichster Kommentar

Wenn Sie nur den Fortschrittsbalken aktualisieren möchten, funktionierte die Verwendung von stream.Position für mich mit großen Dateien, ohne zuerst die gesamte Datei zu lesen:

using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
   var csvReader = new new CsvHelper.CsvReader(sr);
    while (csvReader.Read())
    {
         double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
    }
}

es sollte auch mit GetRecords funktionieren, habe ich aber nicht getestet:

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}

Alle 5 Kommentare

Es gibt einige Möglichkeiten.

  1. Ziehen Sie das Ganze in den Speicher, indem Sie ToList . Sie können dann mehrere Operationen mit den Daten durchführen, einschließlich Count .
  2. Parsen Sie die gesamte Datei. Sie können nur den Parser verwenden, um die gesamte Datei durchzugehen und die Datensätze zu zählen. Dies sollte ziemlich schnell gehen, da keine Klassenobjekte erstellt oder Typkonvertierungen durchgeführt werden.
  3. Zählen Sie einfach die Zeilenenden in der Datei. Sie können dann die Eigenschaft Context.RawRow , um Ihren Fortschritt zu machen.

Vielen Dank,
Ich habe mich schließlich für Methode 2 entschieden.

C# StreamReader sr = File.OpenText(txtBox_CSVFile.Text); int recordsLength = 0; while(sr.ReadLine() != null) { ++recordsLength; } recordsLength--; // discount 1 line because there are column headers in first row. Console.WriteLine("recordsLength : " + recordsLength); sr.Close();

Schließt EnumerateRecords() den Stream automatisch, nachdem alle Einträge hydratisiert wurden? Ich frage mich, ob ich Close() aufrufen soll, nachdem ich die Funktion aufgerufen habe.

Mein Vorschlag ist, in einen using Block einzuschließen.

using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
    int recordsLength = 0;
    while(sr.ReadLine() != null)
    {
        ++recordsLength;
    }
    recordsLength--; // discount 1 line because there are column headers in first row.
    Console.WriteLine("recordsLength : " + recordsLength);
}

Wenn Sie nur den Fortschrittsbalken aktualisieren möchten, funktionierte die Verwendung von stream.Position für mich mit großen Dateien, ohne zuerst die gesamte Datei zu lesen:

using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
   var csvReader = new new CsvHelper.CsvReader(sr);
    while (csvReader.Read())
    {
         double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
    }
}

es sollte auch mit GetRecords funktionieren, habe ich aber nicht getestet:

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}

Ich habe deine Lösung überprüft

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}

was bei mir nicht funktionierte.
Aber das kannst du machen

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)csvReader.Context.CharPosition / csvReader.Context.CharsRead;
}

um das gewünschte Ergebnis zu erzielen

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen