CSV et CSharp

De Banane Atomic
Aller à la navigationAller à la recherche

Parser un fichier csv simple

Csharp.svg
using (var textReader = new StreamReader(csvFilePath))
{
    string line = textReader.ReadLine();

    while (line != null)
    {
        string[] columns = line.Split(';');
        // columns[0] columns[1]

Forcer le séparateur

MonCSV.csv
sep=,

FileHelpers

Bibliothèque .NET qui permet de lire et d'écrire des fichiers CSV, fixed length et delimited records.
Accessible dans NuGet. Licence MIT, GitHub
Stop Rolling Your Own CSV Parser!

Exemple: désérialisation d'un fichier CSV

Csharp.svg
var engine = new FileHelperAsyncEngine<DailyValue>();

// par défaut, en cas d'erreur une exception est levée
// ici on choisit de ne pas lever d'exception, on enregistre l'erreur et on continue
engine.ErrorManager.ErrorMode = ErrorMode.SaveAndContinue;

engine.BeforeReadRecord += (eng, e) =>
{
    // ignore the first 16 lines
    if (e.LineNumber < 17)
    {
        e.SkipThisRecord = true;
    }
    // ignore lines which starts with -
    else if (e.RecordLine.StartsWith("-"))
    {
        e.SkipThisRecord = true;
    }
};

// exclut les Record dont MyProperty == null
engine.AfterReadRecord += (eng, e) =>
{
    if (e.Record.MyProperty == null)
    {
        e.SkipThisRecord = true;
    }
};

var dailyValues = new List<DailyValue>();
// lecture ligne par ligne du fichier
using (engine.BeginReadFile("/path/to/file.csv"))
{
    foreach (DailyValue dv in engine)
    {
        dailyValues.Add(dv);
    }
}

// gestion des erreurs
if (engine.ErrorManager.HasErrors)
{
    foreach (var err in engine.ErrorManager.Errors)
    {
        Console.WriteLine();
        Console.WriteLine("Error on Line number: {0}", err.LineNumber);
        Console.WriteLine("Record causing the problem: {0}", err.RecordString);
        Console.WriteLine("Complete exception information: {0}", err.ExceptionInfo.ToString());
    }
}

Classe de données

La classe est le reflet exact des records, il faut un champs ou propriété par colonne.
Le mapping se fait dans l'ordre.
Csharp.svg
[IgnoreFirst]  // ignore la première ligne du fichier csv
[DelimitedRecord(",")]  // on définit de délimiteur de données
public class DailyValue
{
    // on définit plusieurs formats de date possible
    [FieldConverter(ConverterKind.DateMultiFormat, "MM/dd/yyyy", "dd/MM/yy")]
    public DateTime Date;

    [FieldConverter(ConverterKind.Date, "HH:mm")]
    public DateTime Heure;

    // la valeur est entre guillemets
    [FieldQuoted]
    // on définit le séparateur des décimales
    [FieldConverter(ConverterKind.Single, ",")]
    public float Chiffre;

    // on définit les valeurs correspondant à true et false
    [FieldConverter(ConverterKind.Boolean, "Yes", "No")]
    public bool Choix;

    // champs à ignorer: pas de mapping
    [FieldHidden]
    public string Autre;

    // gestion native des enum
    public MonEnum MonEnum;
}

public enum MonEnum
{
    Elem1,
    Elem2
}