305 votes

Analyse des fichiers CSV en C#, avec en-tête

Existe-t-il un moyen par défaut/official/recommandé de parser les fichiers CSV en C#? Je ne veux pas créer mon propre analyseur.

De plus, j'ai vu des personnes utiliser ODBC/OLE DB pour lire des CSV via le pilote Text, et beaucoup de gens déconseillent cela en raison de ses "inconvénients". Quels sont ces inconvénients?

Idéalement, je cherche un moyen de lire le CSV par nom de colonne, en utilisant le premier enregistrement comme en-tête / noms de champ. Certaines des réponses données sont correctes mais fonctionnent essentiellement pour désérialiser le fichier en classes.

408voto

jitbit Points 8072

Un analyseur de CSV fait maintenant partie du cadre .NET.

Ajoutez une référence à Microsoft.VisualBasic.dll (fonctionne bien en C#, ne tenez pas compte du nom)

using (TextFieldParser parser = new TextFieldParser(@"c:\temp\test.csv"))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    while (!parser.EndOfData)
    {
        //Traiter la ligne
        string[] fields = parser.ReadFields();
        foreach (string field in fields)
        {
            //TODO: Traiter le champ
        }
    }
}

La documentation se trouve ici - Classe TextFieldParser

P.S. Si vous avez besoin d'un exportateur CSV, essayez CsvExport (discl : je suis l'un des contributeurs)

2 votes

De mon expérience, TextFieldParser ne fonctionne pas bien avec de gros fichiers (par exemple, > 250Mo). :(

8 votes

TextFieldParser implémente IDisposable, il est donc préférable de l'utiliser dans une clause using. Bonne réponse par ailleurs.

4 votes

Dans le constructeur, vous voudrez peut-être utiliser un encodage différent de celui par défaut, comme ceci : new TextFieldParser("c:\temp\test.csv", System.Text.Encoding.UTF8)

221voto

Josh Close Points 4901

CsvHelper (une bibliothèque que je maintiens) lira un fichier CSV dans des objets personnalisés.

using (var reader = new StreamReader("chemin\\vers\\fichier.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
    var records = csv.GetRecords();
}

Parfois, vous ne possédez pas les objets que vous essayez de lire. Dans ce cas, vous pouvez utiliser une cartographie fluide car vous ne pouvez pas mettre d'attributs sur la classe.

public sealed class MyCustomObjectMap : CsvClassMap
{
    public MyCustomObjectMap()
    {
        Map( m => m.Property1 ).Name( "Nom de la Colonne" );
        Map( m => m.Property2 ).Index( 4 );
        Map( m => m.Property3 ).Ignore();
        Map( m => m.Property4 ).TypeConverter();
    }
}

8 votes

C'est foutrement rapide. 1,3 million d'enregistrements lus et désérialisés en 10 secondes.

3 votes

Grande bibliothèque très facile à implémenter. Je suggérerais simplement à Josh de mettre à jour sa réponse ici car la bibliothèque a un peu changé depuis la rédaction de cette réponse et vous ne pouvez plus instancier CsvHelper (c'est maintenant seulement un espace de noms) mais vous devez utiliser la classe CsvReader.

0 votes

File.OpenRead() devrait être remplacé par File.OpenText(), car CsvReader() n'accepte pas de filestream en argument de constructeur.

150voto

marc_s Points 321990

Laissez une bibliothèque gérer pour vous tous les détails ennuyeux! :-)

Jetez un coup d'œil à FileHelpers et restez DRY - Don't Repeat Yourself - pas besoin de réinventer la roue pour la millième fois....

Vous devez essentiellement définir la forme de vos données - les champs de votre ligne individuelle dans le CSV - au moyen d'une classe publique (et donc bien réfléchie avec des attributs comme des valeurs par défaut, des remplacements pour les valeurs NULL, etc.), pointer le moteur FileHelpers vers un fichier, et voilà - vous récupérez toutes les entrées de ce fichier. Une seule opération simple - des performances exceptionnelles!

1 votes

Jusqu'à ce que vous ayez besoin de quelque chose de vraiment personnalisé (et la plupart peut de toute façon être implémenté comme extensions), FileHelpers est de loin le meilleur moyen d'y aller, vraiment pratique, testé et performant.

2 votes

@dotnetguy nous sommes en train de sortir la version 3.1 (actuellement 3.1-rc2) est disponible. De plus, nous avons réaménagé le site : www.filehelpers.net vous pouvez télécharger la dernière version à partir de là

1 votes

@MarcosMeli merci beaucoup! J'ai déjà utilisé FileHelpers dans l'un de mes projets et c'était un jeu d'enfant à utiliser - félicitations à l'équipe. Je prévois de faire un article de blog à ce sujet bientôt et au fait - J'adore le nouveau site - bien joué!

32voto

alexn Points 25639

Dans une application professionnelle, j'utilise le projet Open Source sur codeproject.com, CSVReader.

Ça fonctionne bien, et a de bonnes performances. Il y a des tests de performance sur le lien que j'ai fourni.

Un exemple simple, copié de la page du projet :

using (CsvReader csv = new CsvReader(new StreamReader("data.csv"), true))
{
    int fieldCount = csv.FieldCount;
    string[] headers = csv.GetFieldHeaders();

    while (csv.ReadNextRecord())
    {
        for (int i = 0; i < fieldCount; i++)
            Console.Write(string.Format("{0} = {1};", headers[i], csv[i]));

        Console.WriteLine();
    }
}

Comme vous pouvez le constater, c'est très facile à utiliser.

21voto

user1131926 Points 337

Je sais que c'est un peu tard mais je viens de trouver une bibliothèque Microsoft.VisualBasic.FileIO qui a la classe TextFieldParser pour traiter les fichiers CSV.

1 votes

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X