3 votes

C# CSV division dynamique

Je possède plusieurs fichiers CSV de 1,5 Go qui contiennent des informations de facturation sur plusieurs comptes pour des clients d'un fournisseur de services. J'essaie de diviser le grand fichier CSV en plus petits morceaux pour traiter et formater les données à l'intérieur.

Je ne veux pas développer mon propre analyseur CSV mais c'est quelque chose que je n'ai pas encore vu donc corrigez-moi si je me trompe. Les fichiers de 1,5 Go contiennent des informations dans l'ordre suivant : informations sur le compte, numéro de compte, date de facturation, transactions, hors taxes, toutes taxes comprises, type et autres lignes.

Notez que la date de facturation ici signifie la date à laquelle la facture a été émise, donc parfois nous avons plus de deux dates de facturation dans le même CSV.

Les factures sont regroupées par : Numéro de compte > Date de facturation > Transactions.

Certains comptes ont 10 lignes de détails de transaction, d'autres ont plus de 300 000 lignes de détails de transaction. Un grand fichier CSV de 1,5 Go contient environ 8 millions de lignes de données (j'utilisais UltraEdit auparavant) pour couper et coller en morceaux plus petits, mais cela est devenu très inefficace et un processus long.

Je veux simplement charger les grands fichiers CSV dans mon WinForm, cliquer sur un bouton, qui divisera ces grands fichiers en morceaux ne dépassant pas 250 000 lignes, mais certaines factures sont en fait plus grandes que 250 000 lignes, auquel cas les laisser en un seul morceau et ne pas diviser les comptes sur plusieurs fichiers puisqu'ils sont déjà classés de toute façon. De plus, je ne veux pas de comptes avec plusieurs dates de facturation dans le CSV, auquel cas le diviseur peut créer une autre division supplémentaire.

J'ai déjà une application WinForm qui formate les CSV en fichiers plus petits automatiquement dans VS C# 2010.

Est-il réellement possible de traiter ces très grands fichiers CSV? J'ai essayé de charger les grands fichiers mais MemoryOutOfException est un problème agaçant car cela plante à chaque fois et je ne sais pas comment le résoudre. Je suis ouvert aux suggestions.

Voici ce que je pense que je devrais faire :

  • Charger le grand fichier CSV (mais échoue à cause de l'exception OutOfMemory). Comment résoudre ce problème ?
  • Grouper les données par nom de compte, date de facturation et compter le nombre de lignes pour chaque groupe.
  • Ensuite, créer un tableau d'entiers.
  • Transmettre ce tableau d'entiers à un processus de fractionnement de fichiers qui prendra ces tableaux et écrira les blocs de données.

Toute suggestion sera grandement appréciée.

Merci.

2voto

Chris Fulstow Points 19762

Vous pouvez utiliser CsvReader pour parcourir en continu et analyser les données, sans avoir besoin de les charger entièrement en mémoire d'un seul coup.

1voto

Issa Fram Points 675

Oui, à ce sujet.... être à court de mémoire arrivera avec des fichiers qui sont ÉNORMES. Vous devez prendre votre situation au sérieux.

Comme avec la plupart des problèmes, divisez tout en étapes.

J'ai déjà eu une situation similaire auparavant (grand fichier de données au format CSV, besoin de le traiter, etc).

Ce que j'ai fait :

Faire de l'étape 1 de votre programme une simple découpe de votre énorme fichier en plusieurs fichiers plus petits. J'ai divisé des fichiers chiffrés PGP de 5 Go (après déchiffrement... c'est un autre casse-tête) en plusieurs morceaux plus petits. Vous pouvez faire quelque chose de simple comme les numéroter séquentiellement (c'est-à-dire 001, 002, 003...)

Ensuite, créez une application pour le traitement des ENTRÉES. Pas de logique métier réelle ici. Je déteste l'E/S DE FICHIER passionnément quand il s'agit de logique métier et j'adore la sensation réconfortante que donne le fait que les données se trouvent dans une belle base de données SQL Server. C'est juste moi. J'ai créé un pool de threads et j'ai un certain nombre de threads (comme 5, vous décidez de ce que votre machine peut gérer) qui lisent ces fichiers .csv que vous avez créés.

Chaque thread lit un fichier. Une relation un à un. Parce qu'il s'agit d'une E/S de fichier, assurez-vous de ne pas en avoir trop qui s'exécutent en même temps. Chaque thread effectue la même opération de base. Il lit les données, les place dans une structure de base pour la base de données (format de tableau), effectue de nombreuses insertions, puis termine le thread. J'ai utilisé LINQ pour SQL car tout est fortement typé et tout ça, mais chacun ses goûts. Plus la conception de la base de données est bonne, mieux c'est pour vous plus tard pour faire de la logique.

Une fois que tous les threads ont fini de s'exécuter, vous avez toutes les données du fichier CSV d'origine dans la base de données. Maintenant, vous pouvez faire toute votre logique métier et faire tout ce que vous voulez à partir de là. Ce n'est pas la solution la plus esthétique, mais j'ai été forcé de développer cela compte tenu de ma situation/flux de données/taille/exigences. Vous pourriez opter pour quelque chose de complètement différent. Juste partager je suppose.

0voto

Vlad Points 7354

Vous pouvez utiliser un tri externe. Je suppose que vous devriez effectuer un premier passage à travers le fichier pour identifier les frontières de lignes appropriées, car les enregistrements CSV ne sont probablement pas de longueur fixe.

Idéalement, il pourrait y avoir des implémentations de tris externes prêtes à l'emploi pour .NET que vous pourriez utiliser.

0voto

Tim Points 15635

Il existe une classe très utile dans l'espace de noms Microsoft.VisualBasic.FileIO que j'ai utilisée pour traiter les fichiers CSV - la Classe TextFieldParser.

Cela peut ne pas aider avec la taille des fichiers, mais c'est intégré et gère les champs entre guillemets et non entre guillemets (même s'ils sont mélangés sur la même ligne). Je l'ai utilisé plusieurs fois dans des projets au travail.

Malgré le nom de l'assembly, il peut être utilisé avec C#, au cas où vous vous poseriez des questions.

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