web-dev-qa-db-fra.com

Analyse du fichier .csv dans un tableau 2D

J'essaie d'analyser un fichier CSV dans un tableau 2D en C #. J'ai un problème très étrange, voici mon code:

string filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
StreamReader sr = new StreamReader(filePath);
data = null; 
int Row = 0;
while (!sr.EndOfStream)
{
    string[] Line = sr.ReadLine().Split(',');
    if (Row == 0)
    {
        data = new string[Line.Length, Line.Length];
    }
    for (int column = 0; column < Line.Length; column++)
    {
        data[Row, column] = Line[column];
    }
    Row++;
    Console.WriteLine(Row);
}

Mon fichier .csv contient 87 lignes, mais il y a un problème étrange dans l'exécution: les 15 premières lignes du tableau de données sont lues exactement comme prévu, mais lorsque la ligne data[Row, column] = Line[column]; apparaît pour la 16e fois, elle semble tout simplement rompre. hors de la boucle entière (sans respecter la condition sr.EndOfStream) et ne plus lire de données dans le tableau de données. 

Quelqu'un peut-il expliquer ce qui pourrait se passer?

12
user1296932

Rien dans votre code n'obtient le nombre de lignes de votre fichier à temps pour l'utiliser. 

Line.Length représente le nombre de colonnes de votre csv, mais il semblerait que vous essayiez également de l'utiliser pour spécifier le nombre de lignes de votre fichier.

Cela devrait vous permettre d'obtenir le résultat attendu:

string filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
StreamReader sr = new StreamReader(filePath);
var lines = new List<string[]>();
int Row = 0;
while (!sr.EndOfStream)
{
    string[] Line = sr.ReadLine().Split(',');
    lines.Add(Line);
    Row++;
    Console.WriteLine(Row);
}

var data = lines.ToArray();
11
Khan

Une version plus courte du code ci-dessus:

var filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
var data = File.ReadLines(filePath).Select(x => x.Split(',')).ToArray();

Notez l'utilisateur ReadLines au lieu de ReadAllLines, ce qui est plus efficace pour les fichiers plus volumineux, comme indiqué dans documentation MSDN :

Lorsque vous utilisez ReadLines, vous pouvez commencer à énumérer la collection de chaînes avant que la collection entière ne soit renvoyée. lorsque vous utilisez ReadAllLines, vous devez attendre que l'ensemble du tableau de chaînes soit renvoyé avant de pouvoir accéder au tableau. Par conséquent, lorsque vous travaillez avec de très gros fichiers, ReadLines peut être plus efficace.

14
Pavel Bastov

Ceci est identique à celui posté par Pavel, mais il ignore les lignes vides qui peuvent provoquer le blocage de votre programme.

var filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";

string[][] data = File.ReadLines(filepath).Where(line => line != "").Select(x => x.Split('|')).ToArray();
3
JeffS

Avec la boîte de dialogue Ouvrir un fichier

OpenFileDialog opn = new OpenFileDialog();

        if (opn.ShowDialog() == DialogResult.OK)
        {
           StreamReader sr = new StreamReader(opn.FileName);

           List<string[]> data = new List<string[]>(); 

           int Row = 0;

           while (!sr.EndOfStream)
           {
               string[] Line = sr.ReadLine().Split(',');
               data.Add(Line);
               Row++;
               Console.WriteLine(Row);
           }


        }
0
David

Sans connaître le contenu de votre fichier csv, je suppose que l'erreur est générée par cette ligne:

if (Row == 0)
{
    data = new string[Line.Length, Line.Length];
}

En initialisant le nombre total de lignes sur le nombre de colonnes dans la première ligne du fichier csv, vous supposez que le nombre de lignes est toujours égal au nombre de colonnes.

Dès que le nombre de lignes est supérieur au nombre total de colonnes de la première ligne du fichier .csv, vous allez saturer le tableau data en tentant d'accéder à une ligne qui n'y est pas.

Vous pouvez simplifier votre code en remplaçant votre data par une liste permettant l'ajout dynamique d'éléments:

string filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
StreamReader sr = new StreamReader(filePath);
List<string> data = new List<string[]>();
int Row = 0;
while (!sr.EndOfStream)
{
    string[] Line = sr.ReadLine().Split(',');
    data.Add(Line);
    Row++;
    Console.WriteLine(Row);
}
0
matthewrdev