438 votes

Lecture d'un fichier CSV et stockage des valeurs dans un tableau

J'essaie de lire un *.csv -fichier.

El *.csv Le fichier est composé de deux colonnes séparées par un point-virgule ("". ; ").

Je suis capable de lire le *.csv -en utilisant StreamReader et en étant capable de séparer chaque ligne en utilisant la balise Split() fonction. Je veux stocker chaque colonne dans un tableau séparé et ensuite l'afficher.

Est-ce possible de le faire ?

2 votes

@Marc : malheureusement, dans les cultures non anglaises (par exemple, l'italien), lorsque vous enregistrez un fichier excel en CSV, il utilise la méthode suivante ";" comme séparateur... cela a fait de CSV un non-standard imo :(

31 votes

Je lis toujours CSV comme character-separated-values puisque les gens appellent les fichiers CSV même s'ils n'utilisent pas de virgule comme séparateur. Et il y a tellement de dialectes avec des règles de citation ou d'échappement différentes dans la pratique que l'on ne peut pas vraiment parler d'une norme même si en théorie il y a une RFC.

6 votes

Le nom d'extension du fichier CSV devrait maintenant être changé en DSV. Valeurs séparées par des délimiteurs Fichier

577voto

Michael M. Points 868

Vous pouvez le faire comme ceci :

using System.IO;

static void Main(string[] args)
{
    using(var reader = new StreamReader(@"C:\test.csv"))
    {
        List<string> listA = new List<string>();
        List<string> listB = new List<string>();
        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            var values = line.Split(';');

            listA.Add(values[0]);
            listB.Add(values[1]);
        }
    }
}

8 votes

Merci pour cela, j'avais oublié comment séparer les lignes dans un fichier csv (je suis bête !) mais votre solution m'a aidé :)

2 votes

.EndOfStream n'est pas disponible dans .NET 1.1. Est-ce que l'utilisation de while (reader.WriteLine) est la solution ?

2 votes

@ClayShannon La mise en œuvre de EndOfStream vérifie plus ou moins si la position actuelle du lecteur est inférieure à la longueur du nombre total d'octets dans le fichier. Cela fonctionne pour moi dans mon constructeur while rdr.BaseStream.Position < rdr.BaseStream.Length . Souvenez-vous d'un StreamReader est juste une enveloppe pratique autour d'un Stream Cela étant dit, vous pouvez mettre en œuvre vos propres méthodes personnalisées si votre version de .NET n'en dispose pas.

91voto

as-cii Points 7028

À la manière de LINQ :

var lines = File.ReadAllLines("test.txt").Select(a => a.Split(';'));
var csv = from line in lines
          select (from piece in line
                  select piece);

^^Faux - Modifié par Nick

Il semble que la personne qui a répondu à l'origine essayait de remplir csv avec un tableau à 2 dimensions - un tableau contenant des tableaux. Chaque élément du premier tableau contient un tableau représentant le numéro de ligne et chaque élément du tableau imbriqué contient les données de cette colonne spécifique.

var csv = from line in lines
          select (line.Split(',')).ToArray();

2 votes

Peut-être que je rate quelque chose, mais je ne suis pas sûr de l'intérêt de votre variable csv - ne faites-vous pas que recréer la même structure de données qui est déjà dans les lignes ?

0 votes

@Ben : Je pense que vous devez apprendre soit Link Wray soit la méthode LINQ. Malheureusement pour moi, cela ne fonctionnera pas dans .NET 1.1.

0 votes

@ClayShannon Je suis très à l'aise avec LINQ, c'est pourquoi je ne comprends pas l'intérêt de la déclaration, qui (à moins que je ne manque quelque chose) aboutit exactement à la même structure de données que celle avec laquelle vous avez commencé.

41voto

digEmAll Points 24336

Vous ne pouvez pas créer un tableau immédiatement car vous devez connaître le nombre de lignes depuis le début (et cela nécessiterait de lire le fichier csv deux fois).

Vous pouvez stocker des valeurs dans deux List<T> et ensuite les utiliser ou les convertir en un tableau en utilisant List<T>.ToArray()

Un exemple très simple :

var column1 = new List<string>();
var column2 = new List<string>();
using (var rd = new StreamReader("filename.csv"))
{
    while (!rd.EndOfStream)
    {
        var splits = rd.ReadLine().Split(';');
        column1.Add(splits[0]);
        column2.Add(splits[1]);
    }
}
// print column1
Console.WriteLine("Column 1:");
foreach (var element in column1)
    Console.WriteLine(element);

// print column2
Console.WriteLine("Column 2:");
foreach (var element in column2)
    Console.WriteLine(element);

N.B.

Veuillez noter qu'il ne s'agit que d'une exemple très simple . Utilisation de string.Split ne tient pas compte des cas où certains enregistrements contiennent le séparateur ; à l'intérieur.
Pour une approche plus sûre, envisagez d'utiliser des bibliothèques spécifiques à csv comme CsvHelper sur nuget.

1 votes

Ne tient pas compte de ; faire partie de la valeur, exemple "value with ; inside it" . CSV entoure les valeurs contenant des caractères spéciaux avec des guillemets doubles pour indiquer qu'il s'agit d'une chaîne littérale.

2 votes

@ChickenFeet : bien sûr, c'est la raison de la légende : "Exemple très simple" . De toute façon, je peux ajouter une note à ce sujet ;)

1 votes

Pas d'inquiétude, j'ai remarqué que beaucoup d'autres réponses ici n'en tiennent pas compte non plus :)

36voto

Paul Points 8943

J'utilise habituellement ceci analyseur syntaxique de codeproject puisqu'il y a un tas d'échappatoires de caractères et autres qu'il gère pour moi.

3 votes

Cette chose est très bonne et rapide. Si vous êtes dans une situation professionnelle et que vous avez besoin de craquer, utilisez-le.

10 votes

Ce parseur est disponible dans la galerie Nuget sous le nom de LumenWorks.Framework.IO, au cas où vous ne voudriez pas vous inscrire à CodeProject pour le télécharger.

34voto

tomsv Points 2565

Voici ma variante de la réponse la plus votée :

var contents = File.ReadAllText(filename).Split('\n');
var csv = from line in contents
          select line.Split(',').ToArray();

El csv peut alors être utilisée comme dans l'exemple suivant :

int headerRows = 5;
foreach (var row in csv.Skip(headerRows)
    .TakeWhile(r => r.Length > 1 && r.Last().Trim().Length > 0))
{
    String zerothColumnValue = row[0]; // leftmost column
    var firstColumnValue = row[1];
}

0 votes

Comment accéder aux lignes et aux colonnes de la variable csv ?

1 votes

Comment gérer les virgules d'échappement ?

0 votes

Ne gère pas les virgules dans les colonnes. Il est préférable d'utiliser la bibliothèque robuste CsvHelper selon l'avis de joshb réponse

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