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

Modules Perl Discussion :

Sérialisation de données


Sujet :

Modules Perl

  1. #1
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut Sérialisation de données
    Bonjour,

    Le module Tie::File permet d'utiliser par l'intermédiaire d'un tableau, les données stockées dans un fichier, ce fichier pouvant avoir une taille importante, sans que cela ne pose de problème de mémoire.

    Le module Storable lui, permet de stocker dans un fichier, les données de scalaires, tableaux, ou hash même si ces données sont complexes, et de les récupérer ensuite.

    Y a-t-il un moyen de combiner le fonctionnement de ces 2 modules, c'est-à-dire, utiliser de façon transparente par l'intermédiaire d'un tableau les données provenant de structures complexes stockées dans un fichier ?

    Merci à tous ceux qui ont des connaissances sur le sujet.

    Krys006

  2. #2
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut Quelques précisions
    Bonjour,

    Encore moi. Ma question manque sans doute de précision. Entrons un peu plus dans le détail.

    Je travaille sur une appi en Tk, qui lors d'une session de travail produit un certain nombres de données que je souhaiterai mémoriser dans un fichier, pour une utilisation ultétieure. Pour généraliser le problème j'utilise des notations 'génériques'.

    Les données sont stockées dans les variables d'instances d'objets de la classe MyObjet. Pour simplifier je fait apparaître seulement les différents types de variables contenues dans la structure. A la suite d'un traitement, on peut donc obtenir des objets du type :
    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
     
    objet_1 = MyObjet->new (  scalaire    => 'valeur_1',
     
                              ref_tab     => ['v11','v12','v13','v14','v15','v16','v17','v18','v19','v110'],	
     
                              ref_tab_ref => {'ref_11','ref_12','ref_13','ref_14','ref_15','ref_16','ref_17','ref_18','ref_19','ref_110'},
     
    		       );
     
    objet_2 = MyObjet->new (  scalaire    => 'valeur_2',
     
                              ref_tab     => ['v21','v22','v23','v24','v25','v26','v27','v28','v29','v210'],	
     
                              ref_tab_ref => {'ref_21','ref_22','ref_23','ref_24','ref_25','ref_26','ref_27','ref_28','ref_29','ref_210'},
     
    		      );
    etc.

    La 2eme donnée d'un objet est une référence sur un tableau de scalaires.

    La 3eme donnée d'un objet est une référence sur un tableau de références vers des tableaux de scalaires.

    A la suite d'une session de travail, j'obtiens un tableau contenant les références vers tous les objets construits. Son contenu ressemble à ;

    @resultats_session = ('ref_obj_1','ref_obj_2','ref_obj_3', ... ,'ref_obj_n');


    Si j'utilise le module Tie::File pour lier le tableau à un fichier, de la manière suivante :

    Tie ( @resultats_session, 'Tie::File', 'mon_fichier');

    ça fonctionne, à savoir que je peux manipuler les éléments du tableau comme s'il s'agissait d'un tableau habituel, sauf que les éléments sont stockés dans le fichier. Si le tableau devient très grand, je n'aurai pas de problème de mémoire et je n'ai pas à m'occuper des opérations de lecture/écriture dans le fichier.

    Le problème est que si je regarde le contenu du fichier, dont chaque ligne représente un élément du tableau, il contient quelque chose comme ceci :

    MyObjet=HASH(0x31ece94)
    MyObjet=HASH(0x31ech96)
    MyObjet=HASH(0x32ach36)

    .....
    Ce qui bien sûr ne me permet pas de récupérer mes données !

    Donc, est-il possible de lier le tableau @resultats_session à un fichier, de manière à ce que le contenu complet d'un objet lié à élément du tableau soit sauvegardé dans le fichier, au fur et à mesure de leur création.

    Le module Storable s'utilise d'une autre façon. A la suite d'une session, l'instruction :

    store(\@resultats_session, 'mon_fichier');

    sauvegarde complètement le contenu de tous les objets contenus dans le tableau. De plus, on peut bien sûr récupérer tout ce contenu stocké dans un fichier par la commande :

    my $ref_historique_session = retrieve('mon_fichier') or die "$!\n";

    qui récupère une référence, permettant de reconstruire le tableau d'origine :

    @historique_session = @$ref_historique_session;

    Le souci, c'est que je peux faire cela, uniquement à la fin d'une session de travail, et non de manière continue. Or, si le nombre de données devient trop important, il va se produire inévitablement un problème de mémoire, ce qui n'est pas le cas lorsque l'on sauvegarde un tableau ordinaire avec le module Tie.

    Voilà, j'espère avoir été un peu plus clair et que quelqu'un pourra m'apporter au moins un début de solution.

    Merci d'avance à tous ceux qui pourront m'aider.


    Krys006

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Peut-être utiliser Tie pour manipuler tes données et, quand tu as fini, relire le hash associé au fichier pour alimenter un vrai fichier sérialisé avec Storable.

    Je n'ai pas essayé, mais je pense que ça devrait sans doute marcher.

    Sinon, il y a peut-être des solutions en faisant appel à la fonction tie de Perl, à Data:umper (puis eval à la relecture) ou à dbmopen.

  4. #4
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut
    Merci pour ces deux propositions.

    Après avoir glâné quelques infos sur le net, j'avais assez rapidement abandonné l'idée d'utiliser Data :: Dumper, car, comme celui-ci stocke les infos dans un fichier avec du code Perl permettant de les reconstruire, cette méthode peu réserver des surprises, d'après ce que j'ai pu lire.

    Le module Storable quand à lui, sérialise les données sous forme binaire, ce qui donne un stockage plus compact et évite les problèmes liés à l'évaluation du code généré par Data :: Dumper.

    Dans un premier temps, je serai donc plus intéressé par ta première solution, bien que je ne saisisse pas tout correctement.

    Si j'ai bien compris, tu proposes d'utiliser tie pour stocker les données de chaque objet, séparément. Je suis d'accord, mais jusqu'à présent j'ai seulement réussi à écrire dans le fichier les scalaires contenus dans un tableau à raison d'un élément du tableau par ligne du fichier. Comme je le disais, s'il s'agit de références vers des structures de données complexes, je me retrouve uniquement avec les références et pas de données.

    Mais en supposant que ça fonctionne, pour chaque objet, il me faudrait pour sauvegarder tous les objets créés lors d'une session, reconstruire le tableau complet en mémoire avant de sérialiser l'ensemble de façon binaire avec Storable, or c'est ce que j'aurais souhaité éviter à cause du risque de saturation de la mémoire lorsque le nombre de données d'une session devient important.

    Mais je n'ai peut-être pas bien tout saisi.


    Krys006

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    L'idée est d'utiliser Tie pour faire tout ton travail sur les données.

    Quand ton programme est fini, il faut alors itérer sur les données que tu as préparées pour les stocker dans un fichier à l'aide de Storable.

    Je ne connais pas suffisamment Storable pour savoir si c'est vraiment possible, mais le point important est d'itérer sur tes données au lieu de les charger d'un seul coup en mémoire. Je pense que c'est possible, mais je n'ai pas essayé.

    De même que, dans la mesure du possible, quand j'ai un très gros fichier à retraiter (et je retraite des fichiers dépassant souvent les 10 GO), je ne le charge surtout pas en mémoire en le "slurpant" d'une façon ou d'une autre, mais je traite ligne par ligne pour ne jamais occuper beaucoup de mémoire.

    Après il faut faire des essais, je ne garantis pas du tout que ça marche. Je pense juste que ça devrait en principe marcher.

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Je viens de penser à deux autres solutions de sérialisation des données envisageables: JSON et YAML. Toutes les deux ont de puissantes implémentations dans des modules Perl.

    Le module JSON assure la conversion automatique des structures de données Perl en JSON et vice-versa. Le module YAML doit faire à peu près la même chose (en YAML), mais je ne le connais pas plus que cela.

  7. #7
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut
    Je réponds à ta question d'hier soir, 20h51.

    J'ai essayé l'utilisation du module Tie, ça semble marcher pour la sauvegarde, mais j'ai un souci pour la récupération. La façon de procéder est la suivante :

    Au lieu de stocker dans le tableau @resultats_session des références sur les objets créés pendant une session, je stocke les données des objets sérialisés en une chaine de caractères en utilisant la fonction freeze du module Storable (si j'ai bien compris cette fonction place toutes les données contenues dans la structure objet les unes à la suite des autres). Chaque élément du tableau peut donc contenir une donnée assez grande, mais l'association de ce tableau avec un fichier grâce au module Tie devrait résoudre le problème de stockage en mémoire. Pour cette étape je procède ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    tie ( @resultats_session, 'Tie::File', 'fichier_session_X');	# Le tableau est associé à un fichier de sauvegarde
     
    my $serialized = freeze(\$objet_n);				# Données de l'objet sérialisées en une chaine de façon binaire
     
    push @resultats_session,$serialized;				# J'ajoute cette chaîne dans le tableau
    A chaque création d'un nouvel objet, on peut constater sa répercution sur le contenu du fichier, donc le processus semble fonctionner.

    On pourrait dire que j'y suis presque, mais le problème suivant se pose pour la récupération.

    Supposons que pour cette étape j'utilise un autre tableau réservé à la lecture de données obtenues dans des sessions précédentes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    tie ( @historique_session, 'Tie::File', 'fichier_session_Y');	# Le tableau est associé à un fichier sauvegardé auparavant
     
    my $ref = thaw ( $historique_session[0]) 			# Je récupère une ref sur la permière chaîne du tableau correspondant à un objet sérialisé
     
    print "$ref\n";							# Affiche : REF		# Il s'agit d'une référence mais sur rien pour l'instant
     
    my $objet = bless $ref, 'MyObjet';		                # J'essaie de reconstruire l'objet à partir des données contenues à partir de l'adresse $ref
     
    print $objet->obtenir_scalaire();				# Ne fonctionne pas !
    Le message d'erreur est : "Not a HASH reference at MyObjet.pm"

    Je ne parvient pas à reconstruire la structure de l'objet. Je me suis basé sur un exemple de la doc de Storable sur le cpan, qui sérialise en mémoire un objet de type hash, puis construit une copie du hash à partir de la fonction thaw.


    # Serializing to memory
    $serialized = freeze \%table;
    %table_clone = %{ thaw($serialized) };

    Mais là je bloque un peu. Il faudrait que je comprenne exactement ce que fait la fonction freeze.

    Je continue à chercher et en attendant de trouver, merci Lolo78 pour ton aide.


    Krys006

  8. #8
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut Je pense avoir trouvé
    Après réflexion j'ai compris la raison pour laquelle je n'arrivais pas à reconstruire en mémoire la structure de l'objet sauvegardé.

    Dans le premier morceau de code, il faut remplacer à la ligne 4 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $serialized = freeze(\$objet_n);
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $serialized = freeze(\%$objet_n);
    car les variables d'un objet de la classe MyObjet ont en fait une représentation sous forme de hash.

    Ainsi, lors de la récupération des données de l'objet sous forme sérialisée, l'instruction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $ref = thaw ( $historique_session[0]);
    crée donc une référence sur un hash, et ensuite la création d'un objet avec les données du hash référencé par $ref fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $objet = bless $ref, 'MyObjet';

    Je vais écrire un bout de code qui fonctionne pour illustrer cette possibilité de stocker des structures de données complexes dans un fichier pour les

    réutiliser ensuite.


    Krys006

Discussions similaires

  1. Sérialisation des données Web Service
    Par princessse dans le forum Services Web
    Réponses: 1
    Dernier message: 18/05/2012, 12h03
  2. Sérialisation de données ou autre table
    Par Bakura dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/07/2011, 12h56
  3. sérialisation de données relationnelles
    Par rdh123 dans le forum C#
    Réponses: 0
    Dernier message: 07/09/2009, 10h36
  4. Réponses: 2
    Dernier message: 01/09/2007, 20h59
  5. [C#] Sérialisation et sauvegarde de données
    Par scaleo dans le forum Windows Forms
    Réponses: 4
    Dernier message: 28/07/2006, 12h44

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