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 :

[Méthodologie] File Cleaner


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 50
    Par défaut [Méthodologie] File Cleaner
    Bonjour
    j'aurai besoin de votre aide pour réaliser une sorte de "cleaner".
    (quand j'entend "besoin de votre aide pour réaliser", c'est plus d'une méthodologie que j'ai besoin je n'attend pas du tout du code tout pret)
    je vais essayer de vous expliquer clairement ce que j'entend par cleaner, et le début de la routine que je souhaite mettre en place pour la réaliser.

    Alors :
    J'ai un fichier texte. Ce fichier contient des informations diverses et variées.
    Il contient également certaines informations qui peuvent apparaitre en double dans le fichier.
    J'entends par notion de double la chose suivante :
    j'ai le bloc d'informations suivant :

    createElement ToTo -n "monToto1";
    setVal ".d" -type "float" 1 0 0;
    setVal ".hi" -type "float" 1 0 1;
    setVal ".uk" -type "float" 1 1 0;


    ce bloc commence donc par createElement ToTo et se finira à la fin de la ligne précédent le futur createElement.

    quelque part ailleurs dans mon fichier je peux avoir :
    createElement ToTo -n "monToto2";
    setVal ".d" -type "float" 1 0 0;
    setVal ".hi" -type "float" 1 0 1;
    setVal ".uk" -type "float" 1 1 0;


    ces deux blocs n'ayant pas le même nom, ils seront considérés unique.
    Le but de ce cleaner est justement de reconsidéré la phrase plus haut et de dire
    si dans mon fichier, j'ai deux bloc différents ayant les même attributs alors je réécrirai mon fichier avec un seul bloc

    Chose importante également, pour un futur développement je dois conserver le nom du bloc : -n "monToto1", car plus tard je serai obligé de refaire une passe sur le fichier, pour rechercher si je n'ai pas d'autre occurence de ce nom : quelque chose de ce genre :

    createAttach attach -o "monToto1";
    setAtt ".b" -type "file" "c:\toto\ex.tif";


    car cette attache faisant partie du bloc, je ne dois merger deux blocs en un que s'ils sont rigoureusement identiques
    par ex si j'ai deux blocs identiques au niveau des attributs, mais que un dispose d'une attache comme ci dessous et l'autre non, alors ces deux blocs restent uniques (là ça commence à devenir casse tete :o)


    ça c'est l'explication fonctionnelle
    maintenant techniquement j'éprouve quelques difficultés

    l'idée que j'avais est la suivante

    je récupère le fichier à cleaner et le passe en parametre d'un streamReader
    je boucle tant que mon streamreader.readline() renvoie !null
    je teste ma ligne courante voir si elle contient createElement ToTo
    si oui je dois ajouter cette ligne plus toutes les lignes d'en dessous tant que je ne rencontre pas de nouveau createElement => dans une sorte de buffer facile à manipuler (List<string>)

    etc etc
    maintenant, est ce que je dois créer une liste pour chaque bloc et essayer de comparer (comment ?) ces listes ?

    L'idée suivante
    étant de reparcourir mon stream depuis le début (y a t'il une méthode pour revenir au début d'un stream ?) et de rechercher pour chaque bloc si j'ai une autre occurence du nom du bloc associé à la balise createAttach

    L'idée finale serait donc de flaguer les endroits "identiques" fonctionnellement, pour ensuite réécrire un fichier ayant le même contenu à la différence près que les blocs identiques soient "mergés".

    En espérant que ce ne soit pas trop complexe.
    Je suis disponible pour toute question bien entendu

    Par avance un grand merci pour votre aide

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Il faudrait définir une classe Element qui représenterait un élément avec ses attributs. Ensuite tu lis le fichier et tu crées une instance de la classe Element à chaque élément rencontré dans le fichier.

    Maintenant, pour stocker l'ensemble des classes, je passerais par un dictionnaire (couple clé/valeur avec clé unique) avec la rédéfinition des méthodes Equals et GetHashCode de la classe Element.

    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
    class Element
    {
        // Définition des attributs de l'élément
        ...
     
        public override bool Equals(object obj)
        {
            // Renvoi true si les attributs entre l'élement actuel (this)
            // et l'élement obj sont identiques (mêmes valeurs).
            return this.GetHashCode() == obj.GetHashCode();
        }
     
        public override int GetHashCode()        
        {
            // Renvoi la valeur de hash pour l'élément.
            // Si deux éléments ont les mêmes attributs (mêmes valeurs), 
            // la valeur de hash doit être identique pour les deux élements.
            // A priori, les attaches ne joue pas sur l'unicité donc seuls les attributs comptent.
            ...
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dictionary<Element, string> dico = new Dictionary<Element, string>();
    ...
    Element element = new Element();
    // Assignation des différents valeurs liées à l'élément
    ...
    // Ajout au dicitionnaire
    if (!dico.ContainsKey(element))
    {
        dico.Add(element, "NomDeLElement");
    }
    La rédéfinition des méthodes Equals et GetHashCode, permet de ne pas ajouter un élément possédant les mêmes attributs qu'un élément déjà présent dans le dictionnaire. Ceci est valable uniquement à condition d'avoir correctement calculé le hash dans la méthode GetHashCode() de la classe Element bien évidemment

    En procédant ainsi, tu n'as besoin que d'une passe de lecture pour "nettoyer" les éléments. Dans le dictionnaire tu auras chaque élément présent dans ton fichier, sans doublon. Pour chaque élément tu pourras gérer le nom de l'élément dans la partie valeur du dictionnaire. Dans l'exemple je n'ai stocké que le nom du premier élément trouvé, mais tu peux aussi gérer une liste si tu en as besoin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Dictionary<Element, List<string>> dico = new Dictionary<Element, List<string>>();
    ...
    Element element = new Element();
    // Assignation des différents valeurs liées à l'élément
    ...
    // Ajout au dicitionnaire
    if (!dico.ContainsKey(element))
    {
        dico.Add(element, new List<string>());
    }
    dico[element].Add("NomDeLElement");
    Une fois ce traitement fini, il te suffit de parcourir le dictionnaire pour réécrire les éléments dans un fichier. Il faudra ensuite compléter ce fichier avec les autres "commandes" puisqu'il y en a d'autres à priori.

    Pour les attaches, tu peux parfaitement faire ça sur la même passe de lecture que pour les éléments je pense. Tu te fais une liste des attaches de manière à pouvoir lier à un élément une attache (ou plusieurs ça je ne sais pas) et ensuite tu réécris le tout.

    Un dictionnaire devrait être utile à ce stade aussi. Le nom du bloc en clé et une attache (ou liste d'attache suivant les besoins) en valeur. Pour chaque élément il sera ainsi très simple de récupérer les attaches associés.

    En espérant ne pas être trop à côté de la plaque sur la demande de départ

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 50
    Par défaut
    hello, merci de ton aide, et surtout d'avoir pris le temps de lire tout ce que j'avais écris et en plus d'en avoir écrit autant

    alors fonctionnellement je pense que l'on est pas loin à l'exception près des attaches. En fait si l'on a deux blocs identiques au point de vue des attributs, il peut y avoir un bloc avec attachement et l'autre non. Dans ce cas là les deux bloc ne sont pas identiques.

    je verrai bien une méthode RetrieveAttachements() pour un nom d'element donné.

    ce qui me pose souci dans le code que tu as mis au dessus c'est l'override de GetHash() je vois pas trop comment l'implémenter :$

    pour le reste je trouve ça bien
    l'utilisation d'un dictionnaire est pas mal. La partie la plus complexe selon moi et de réécrire le fichier final "cleané" car pour récupérer 'le reste' je vois pas trop comment m'y prendre, si ce n'est à la premiere lecture d'ajouter chaque ligne dans une List<string> et lorsque je rencontre un element ajouter dans la liste le nom de l'element apres avoir effectué le travail de parsing

    qu'en penses tu ?

    encore merci

  4. #4
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Citation Envoyé par Lostini
    alors fonctionnellement je pense que l'on est pas loin à l'exception près des attaches. En fait si l'on a deux blocs identiques au point de vue des attributs, il peut y avoir un bloc avec attachement et l'autre non. Dans ce cas là les deux bloc ne sont pas identiques.
    Je n'avais pas compris ça comme ça, en relisant je me rend compte de mon erreur en interprétant mal une de tes phrases. Cela reste faisable néanmoins je pense.

    Une première passe se charge de construire la liste des attaches avec un dictionnaire (nom du bloc en clé, données de l'attache en valeur).

    Ensuite, la seconde passe s'occupe de créer les éléments. Il faudra ajouter l'information d'attache dans la classe Element afin d'en tenir compte dans la méthode Equals, car si j'ai bien compris maintenant, dès qu'un élément possède une attache, il ne peut plus être identique à un autre élément.

    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
    class Element
    {
        // Définition des attributs de l'élément
        ...
        private string _attache;
     
        public override bool Equals(object obj)
        {
            // Renvoi true si les attributs entre l'élement actuel (this)
            // et l'élement obj sont identiques (mêmes valeurs).
            // Si l'élément possède une attache, il ne peut être identique avec un autre élément
            if (_attache != null) { return false; }
            else { return this.GetHashCode() == obj.GetHashCode(); }
        }
     
        public override int GetHashCode()        
        {
            // Renvoi la valeur de hash pour l'élément.
            // Si deux éléments ont les mêmes attributs (mêmes valeurs), 
            // la valeur de hash doit être identique pour les deux élements.
            // A priori, les attaches ne joue pas sur l'unicité donc seuls les attributs comptent.
            ...
        }
    }
    Si jamais les attaches sont en premier dans le fichier à traiter, le tout peut être fait en une passe. Mais je doute que ce soit aussi simple

    Pour la méthode GetHashCode(), le plus simple serait que tu me donnes un exemple d'élément en m'indiquant comment il est constituté au niveau des attributs, afin de voir ce qui pourrait convenir
    createElement ToTo -n "monToto1";
    setVal ".d" -type "float" 1 0 0;
    setVal ".hi" -type "float" 1 0 1;
    setVal ".uk" -type "float" 1 1 0;
    Les valeurs .d, .hi. uk ne sont pas les seuls possibles je suppose, ainsi que pour le type (float dans l'exemple) et les valeurs 1 ou 0 suivantes.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 50
    Par défaut
    bonjour,

    je vais encore te poser des questions sur cette méthode GetHashCode()
    j'ai du mal à saisir en fait son utilité :$

    pourquoi devrait on être obligé de passer par une méthode qui renverrai toujours le même code pour un élément donné afin de vérifier l'équivalence ?

    ça éviterai de faire des if à rallonge ?

    par avance merci de ton aide

  6. #6
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    En gros dans un dictionnaire le hashcode d'un objet, obtenu avec la méthode GetHashCode, est utilisé comme clé. La méthode Equals est aussi utilisée mais elle ne te pose pas de problème à priori

    Imaginons que tu ais l'objet element1 avec comme hashcode 320163041 et l'objet element2 avec le même hashcode. Le développeur a choisi de renvoyer un hashcode identique car si les objets sont différents (2 instances différentes donc références différentes), le développeur considère qu'ils représentent le même élément.

    Si le hashcode est identique cela signifie que pour le dictionnaire ces objets ont la même clé. Lorsque l'on veut ajouter un élément dans le dictionnaire, si on en trouve déjà un avec ce hashcode on peut alors considérer que celui que l'on veut ajouter est un doublon.

    Cela revient au code que j'avais mis au début
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Dictionary<Element, string> dico = new Dictionary<Element, string>();
    ...
    Element element = new Element();
    // Assignation des différents valeurs liées à l'élément
    ...
    // Ajout au dictionnaire. 
    // On teste si le dictionnaire ne contient pas déjà l'élément (utilisation du hashcode à ce stade)
    // Si l'élément est déjà présent, alors l'élément actuel est un doublon que l'on ne traite pas
    if (!dico.ContainsKey(element))
    {
        dico.Add(element, "NomDeLElement");
    }
    Au final, cela permet juste une gestion simplifiée des doublons puisque le dictionnaire fait tout le travail. En plus comme l'accès sur un dictionnaire est en O(1), suivant la taille des données cela peut être pratique.

    J'espère que c'est plus clair

Discussions similaires

  1. Réponses: 6
    Dernier message: 30/07/2003, 15h59
  2. passer FILE* en argument d une fonction
    Par Monsieur_Manu dans le forum C
    Réponses: 9
    Dernier message: 10/04/2003, 18h56
  3. [File et Directory ListBox] Soucis de filtre
    Par Mercilius dans le forum Composants VCL
    Réponses: 8
    Dernier message: 04/04/2003, 17h17
  4. A propos des 'File management Functions' de Windows
    Par znaidi dans le forum Windows
    Réponses: 3
    Dernier message: 01/04/2003, 17h01
  5. recupèrer file d'attente d'impression
    Par magic corp. dans le forum Langage
    Réponses: 2
    Dernier message: 25/09/2002, 15h12

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