IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Gérer des fichiers "à pas fixe" ou "record" avec C#


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Gérer des fichiers "à pas fixe" ou "record" avec C#
    Bonjour,

    Je viens de retomber sur un vieux code que j'ai écrit, qui permet de générer un fichier à pas fixe (ou record) à partir d'une description du fichier.

    J'avais essayé de le rendre le plus générique possible (en passant notamment par un fichier de description des champs en XML) mais la solution que j'avais adopté me semble très lourde par rapport à ce que savait faire VB en natif par exemple.

    Exemple de fichier " pas fixe" :

    Nom : String / Position 1 / Longueur 20
    Prenom : String / Position 21 / Longueur 20
    Age : Int / Position 41 / Longueur 3

    J'ai matérialisé les sauts à la ligne par des \n
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Alfred              Dupont              25 \n
    Jules               Desbois             43 \n
    Henriette           Dupuis              103\n
    Ce genre de fichiers sont très utilisés dans les EDI et autres transferts inter-systèmes. Le XML n'a pas tout remplacé, loin de là. Et niveau performances, y'a rien de mieux que ce genre de fichiers, le XML étant une usine à gaz à côté.

    En VB, ça se lisait/écrivait très facilement (à la faute de syntaxe près, ça fait longtemps que j'ai pas fait de VB ^^)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    Type Personne
       Prenom As String*20
       Nom As String*20
       Age As String*3
       CrLf as String*2
    End Type
     
    Sub ReadFile()
      Open FileName For Random Access Read As #FileNbr Len = Len(Personne)
      Dim P as Personne
      Do Until EOF(FileNbr)
         Get #FileNbr, , P
         MsgBox("La personne " & P.Prenom & " " & P.Nom & " a " & P.Age & " ans.")
       Loop
       Close #FileNbr
    End Sub
    En C#, c'est une véritable usine à gaz pour reproduire la même chose, à ma connaissance tout du moins.

    Avant que je poste ce que j'avais fait, déjà, est-ce que vous avez des solutions "génériques" pour faire ça ?
    C'est à dire du code qui évite de noyer 25 sous-chaines avec des nombres magiques sur 50 lignes.

    Le but étant d'avoir en sortie :
    - Un objet représentant une ligne "typée" du fichier (il peu y avoir des personnes, mais aussi d'autres types de records)
    - Dont les champs sont accessibles facilement, comme dans une structure

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Aucun succès, c'est fou !

    Personne n'est amené à travailler avec ce genre de fichiers ?

    Suis-je le seul ?

    Bon, en tout cas, je me suis amusé à réécrire une bibliothèque générique permettant de gérer ce genre de fichiers.

    Actuellement, il s'agit d'une version très basique, qui ne gère qu'un type de record par fichier.

    Je la ferai peut-être évoluer selon vos remarques ou besoins... si quelqu'un daigne poster dans ce topic !

    Voici comment utiliser la lib :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    using System;
    using System.Text;
    using FlatFileManager;
     
    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Définition du format des variables");
     
                FlatFileInfo ffi = new FlatFileInfo("yyyyMMdd", ".", Encoding.ASCII);
     
                Console.WriteLine("Lecture de la définition du format de fichier \"personne\"");
     
                RecordInfo rcp = new RecordInfo("personne");
                FlatFile file = new FlatFile(ffi, rcp);
     
                Console.WriteLine("Lecture du fichier \"personnes.txt\"");
                file.Load("personnes.txt");
     
                foreach (Record r in file)
                {
                    Console.WriteLine("{0} {1} a {2} ans.", r["prenom"], r["nom"], r["age"]);
                }
     
                rcp = new RecordInfo("produit");
                file = new FlatFile(ffi, rcp);
                file.Load("produits.txt");
     
                Console.WriteLine("Lecture du fichier 'produits.txt'");
                foreach (Record r in file)
                {
                    Console.WriteLine("Code : {0} Nom : {1} DLC : {2} Prix : {3} EUR", r["code"], r["nom"], r["dlc"].DateValue.ToShortDateString(), r["prix"]);
                }
     
                rcp = new RecordInfo("test");
                file = new FlatFile(ffi, rcp);
                Record rec = new Record(rcp);
                rec["teststring"].SetValue("test string");
                rec["testdatetime"].SetValue(DateTime.Today);
                rec["testint"].SetValue(12);
                rec["testdecimal"].SetValue(3.45);
                file.Records.Add(rec);
     
                rec = new Record(rcp);
                rec["teststring"].SetValue("test 2");
                rec["testdatetime"].SetValue(DateTime.Today.AddDays(10));
                rec["testint"].SetValue(123);
                rec["testdecimal"].SetValue(4.5);
                file.Records.Add(rec);
     
                file.Save("test.txt");
     
                Console.ReadKey(true);
            }
        }
    }
    Cet exemple charge deux fichiers et affiche leur contenu, avant d'en créer un troisième.

    J'espère que vous la trouverez utile et simple d'utilisation (c'était l'unique but recherché).
    Fichiers attachés Fichiers attachés

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Il y a une classe TextFieldParser qui sait faire ce genre de choses (pour des champs à largeur fixe ou avec séparateurs). Elle est dans l'assembly Microsoft.VisualBasic (va savoir pourquoi), mais rien n'empêche de référencer cet assembly depuis C# et d'utiliser la classe

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Sinon, concernant ta solution, y a juste un truc qui me gêne : l'utilisation d'un singleton pour FlatFileInfo. Ca aurait un sens si tous les fichiers plats avaient le même séparateur et le même format de date, mais dans la vraie vie ce n'est pas le cas... Donc cette info ne devrait pas être globale, elle devrait plutôt être spécifique à chaque fichier plat.

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    C'est effectivement ce que je me suis dis lors de son utilisation, mais c'était pour voir comment marchait un "vrai" singleton

    Je vais y apporter quelques modifications : idem, l'encodage est actuellement en dur, et devrait être dans FlatFileInfo...

    Par contre, je suis un peu deg pour le coup de la class déjà existante... Je vais voir à quoi ça ressemble

  6. #6
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Ca me revient pourquoi j'étais passé par un Singleton

    Comment on fait une variable globale en C# ?

    Bon, j'ai esquivé en mettant les infos en Thread.CurrentThread.CurrentCulture lors du Load et du Save, mais j'aimerais bien savoir comment gérer des variables globales... locales à l'appelant !

    Comme c'est le cas en VB par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Sub Test0
       Call Test1()
    End Sub
     
    Sub Test1
       Dim a as integer
       Call Test2()
    End Sub
     
    Sub Test2
       Dim b as integer
       Call Test3()
    End Sub
     
    Sub Test3
       Dim c as integer
    End Sub
    => Dans Test0, on n'a accès à aucune variable
    => Dans Test1, on a accès à "a"
    => Dans Test2, on a accès à "a" et "b"
    => Dans Test3, on a accès à "a", "b" et "c"

    En .NET ça n'existe pas : on n'a accès qu'aux variables locales à la méthode courante... et aux singletons (ou classes avec contructeur static).

    Le seul souci, c'est que les singletons/classes avec contructeur static, c'est de portée globale à l'application. Moi j'aimerais que si j'ai une instance de FlatFile, une de ses variables soit visible dans tous ses enfants, mais qu'une autre instance de FlatFile puis cohabiter avec d'autres variables.

    Y'a moyen de faire ça ?

Discussions similaires

  1. [SSH2] Utiliser scp pour gérer des fichiers distants
    Par cybercandyman dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 12/11/2007, 17h03
  2. Cherche librairie pour gérer un fichier XML (pas un parser)
    Par batataw dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 20/10/2007, 23h18
  3. Choix SGBD pour gérer des fichiers Excel et des images ?
    Par benoit69 dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 01/03/2007, 12h02
  4. Gèrer des fichiers (documents .doc) via Struts.
    Par LESOLEIL dans le forum Struts 1
    Réponses: 7
    Dernier message: 22/08/2005, 16h26
  5. Réponses: 5
    Dernier message: 28/04/2004, 15h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo