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

Delphi Discussion :

Parcourir un fichier texte sans charger le fichier


Sujet :

Delphi

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Points : 84
    Points
    84
    Par défaut Parcourir un fichier texte sans charger le fichier
    bonjour,

    je recherche un moyen de parcourir un fichier texte sans le charger totalement en memoire de maniere a optimiser ma RAM car j'ai des tres gros fichiers a lire.

    comme methodes je connais le classique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var
        s: TStringList
    begin
        s := TStringList.Create();
        s.LoadFromFile(nomFichier);
    mais pour mon programme c'est beaucoup trop lourd.

    je connais aussi le fameux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var
        fich: TextFile;
        s: String;
    begin
        AssignFile(fich, nomFichier);
        Reset(fich);
        ReadLn(fich,s);
        CloseFile(fich);
    mais ce n'est pas tres pratique pour gerer un grand nombre de chaines de caracteres...

    il n'y aurait pas une autre methode? une methode intermediaire qui permettrait de charger une partie du fichier seulement.

    Mon but final est de detecter si il y a des doublons dans mon fichier (cad des lignes identiques)

    Merci

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Points : 84
    Points
    84
    Par défaut
    je repond a ma propre question: je pourrais faire un ReadLn et transferer chaque ligne X que je rencontre vers une TStringList si X n'appartient pas deja a ma liste. Si X appartient deja a ma liste je peux ecrire "ce fichier contient un doublon".

    Le probleme est que si il n'y a aucun doublon dans mon fichier et qu'il est gros (plusieurs Giga), alors je le chargerai entierement dans ma liste... ce qui signifie une grosse masse de RAM en moins sur mon ordi

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Points : 84
    Points
    84
    Par défaut
    C'est le defi du jour. Si vous trouvez une solution optimale je vous offre une bouteille de champagne (et un bisous)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Points : 84
    Points
    84
    Par défaut
    voila mon programme ('fichiers' est une TStringList contenant les noms des fichiers a analyser):

    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
     
    for i := 0 to fichiers.Count-1 do begin
     
        flag := 0;
     
        lignes.Clear();
     
        AssignFile( fich, fichiers[i] );
        Reset( fich );
     
        while not Eof(fich) do begin
           ReadLn( fich, s );
     
           for j := 0 to lignes.Count-1 do begin
     
              if s = lignes[j] then begin
                memo1.Lines.Add( 'le fichier '+fichiers[i]+' contient un ou plusieurs doublon(s)' );
                flag := 1;
                break;
              end;
     
           end;
     
           if flag = 0 then lignes.Add(s);
           if flag = 1 then break;
     
     
        end;
    si vous trouvez un meilleur algo ca serait cool! la il tourne et apparemment il y en a pour un moment

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 68
    Points : 61
    Points
    61
    Par défaut
    J'ai trouvé ceci....

    Traiter des fichiers de grande taille
    Sylvain James
    TeamB-FR
    Rédaction Developpez.com
    Responsable Delphi

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par Faucon
    J'ai trouvé ceci....

    Traiter des fichiers de grande taille
    Sylvain James
    TeamB-FR
    Rédaction Developpez.com
    Responsable Delphi
    tu n'aurais pas un lien?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 68
    Points : 61
    Points
    61
    Par défaut
    Taper dans Google..
    Traitement des gros fichiers...
    La référence apparaît sous le titre
    "Traitement des gros fichiers-Club d'entraide des dédeloppeurs"

    Bon courage..

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Points : 84
    Points
    84
    Par défaut
    ok merci

  9. #9
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Traitement des gros fichiers (et plus petits aussi je dirais )
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  10. #10
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Oui pas mieux

    LEs Stream sont super puissant pour la gestion des fichiers
    Par contre si le TMemoryStream permet de charger et manipuler un fichier en memoire, le TFileStream, l'ouvre sur le Disque et ne charge en memoire que de quoi le manipuler

    J'ai pas mieux que ca en magazin
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  11. #11
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Tiens, juste une suggestion, si j'avais à résoudre le problème (chercher des lignes-doublons dans un méga-fichier) je serais parti sur le scénario suivant :

    Etape 1 : Avec un FileStrem je scrute le fichier de position:=0 jusqu'à la fin et chaque fois que je rencontre les caractères-de-séparation des lignes j'expédie la position-de-début de la ligne courante et la position-de-fin-de-ligne dans un object qui comporte 3 colonnes et qui shématise donc un tableau dont chaque ligne comporte uniquement trois cases que je nommerais posDebLigne, posFinLigne, et Flag et qui ressemblerait donc à un relevé topographique du fichier.

    Etape 2 : Puisque les doublons sont d'abord des lignes-de-même-longueur, je réserve cette étape à parcourir le tableau précité pour comparer uniquement la longueur de chaque ligne à celle des suivantes et chaque fois que je rencontre l'égalité-de-longueurs-différentes-de-zéro je plante un drapeau-de-correspondance dans la case Flag des lignes-doublons-présumés de mon tableau. Pour achever cette étape de façon clean je delete dans ce tableau toute les lignes qui ne comportent aucun drapeau.

    Etape 3 : Je prélève dans le tableau les positions de début et de fin de la première paire-de-lignes-doublons-de-même-longueur qui portent donc le même drapeau-de-correspondance et je récupère via le FileStream la valeur-string des deux lignes présumées être des doublons et si string1<>string2 alors je continue à faire pareil avec la paire suivante mais si string1=string2 alors je sauve le résultat de ce repérage de doublon dans l'object de mon choix.

    Remarque : on peut envisager de mener les Etapes 2 et 3 en parallèle surtout si on veut faire un Exit-Passons-au-Fichier-suivant dès le repérage du 1er doublon.

    Avantages : Comme on ne charge ainsi en memoire-vive uniquement le tableau du relevé topographique du fichier ainsi que string1 et string2 on peut ainsi s'attaquer à de très gros fichiers avant de risquer de saturer la mem-vive.
    De plus si un doublon est formé par la 1ère et la dernière ligne d'un Méga-fichier il est ainsi repérable aisément alors qu'il faudrait une usine à gaz pour y arriver en envisageant par exemple d'envoyer en mem-vive une succession de morceaux du Méga-fichier pour chercher, morceau après morceau, ou essayer de trouver un doublon qui a un pied dans le premier morceau et l'autre pied dans le dernier morceau.

    P.S : ce que j'ai appelé "tableau" ci-dessus avec ses 3 colonnes peut, on a l'embarras du choix, être formé par 3 StringList, un Tableau-Dynamique à trois colonnes, etc à chacun le choix de ses outils. (Au fait il me semble avoir vu qq part sur ce forum le code d'un "TIntegerList" qui contrairement à TStringList accepte posDeb etc sans nécessiter de conversion Longint>String et vice-versa et qui de plus éviterait les inconvénients des tableaux dits dynamiques... à vérifier)
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  12. #12
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Une solution sans charger du tout le fichier.
    Consiste à créer dans un premier temps une liste des offsets.
    Mais c'est trèèèèèèèèèèès lent !!!

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    // Lecture d'une chaîne délimitée par un retour chariot
    // à la position courante d'un flux.
    function ReadStringFromStream(var S:TFileStream;Offset:Int64):string;
     var k:Char;
     begin
      Result := '';
      S.Position := Offset;
      S.Read(k,SizeOf(k));
      while (S.Position < S.Size) and not(k in [#10,#13]) do
       begin
        Result := Result + k;
        S.Read(k,SizeOf(k));
       end;
      if (S.Position < S.Size) and (k = #13) then
       begin
        S.Read(k,SizeOf(k));
        if k <> #10 then S.Position := S.Position - 1;
       end;
     end;
     
    procedure JumpToNextStringInStream(var S:TFileStream);
     var k:Char;
     begin
      S.Read(k,SizeOf(k));
      while (S.Position < S.Size) and not(k in [#10,#13]) do S.Read(k,SizeOf(k));
      if (S.Position < S.Size) and (k = #13) then
       begin
        S.Read(k,SizeOf(k));
        if k <> #10 then S.Position := S.Position - 1;
       end;
     end;
     
    procedure Doublons(FileName:string;Str:TStrings;Lab:TLabel;PB:TProgressBar); // ComCtrls
     var S         : TFileStream;
         Offsets   : Array of Int64;
         L,I,J     : Integer;
         Line      : String;
         C,M       : Int64;
     begin
      S := nil;
      try
       try
        S := TFileStream.Create(FileName,fmOpenRead);
        if Assigned(PB) then PB.Max := 100;    // TProgressBar
        if Assigned(Str) then Str.Clear;
        // Création liste des offsets de lignes
        if Assigned(Lab) then
             begin
              Lab.Caption := Format('Création de la liste des offsets - taille du fichier : %d octets',[S.Size]);
              Lab.Update;
             end;
        while S.Position < S.Size do
         begin
          if Assigned(PB) then PB.Position := 100 * S.Position div S.Size;
          L := Length(Offsets);
          SetLength(Offsets,L + 1);
          Offsets[L] := S.Position;
          JumpToNextStringInStream(S);
         end;
        L := Length(Offsets);
        L := 1000;
        C := 0;
        M := L * (L - 1) div 2;
        if M <= 0 then M := 1;
        if Assigned(Str) then Str.BeginUpdate;
        if Assigned(PB) then PB.Position := 0;
        for I := 0 to L - 2 do
         begin
          Line := ReadStringFromStream(S,Offsets[I]);
          if Assigned(Lab) then
             begin
              Lab.Caption := Format('Recherche des doublons - ligne %d / %d',[I+2,L]);
              Lab.Update;
             end;
          for J := I + 1 to L - 1 do
           begin
            inc(C);
            if Line = ReadStringFromStream(S,Offsets[J])
             then begin
                   // Hiii, un doublon !
                   // Ici, on peut faire ce qu'on veut, stocker le doublon
                   // contenu dans Line dans un TStringList par exemple.
                   if Assigned(Str) then Str.Add(Format('Lignes %d et %d (%s)',[I,J,Line]));
                   if Assigned(PB) then PB.Position := 100 * C div M;
                  end
           end
         end;
        if Assigned(Str) then Str.EndUpdate;
       except
        On E:Exception do ShowMessage(E.Message);
       end;
      finally
       if S <> nil then FreeAndNil(S);
       Finalize(Offsets);
      end;
     end;
    Exemple d'utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Doublons('Monfichier.txt',Memo1.Lines,Label1,ProgressBar1);

  13. #13
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Ah ! J'ai posté en même temps que Gilbert Geyer... Remarque : son idée est excellente, et mon code peut servir de plate forme de départ pour implémenter son idée !

  14. #14
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par Gilbert Geyer
    (Au fait il me semble avoir vu qq part sur ce forum le code d'un "TIntegerList" qui contrairement à TStringList accepte posDeb etc sans nécessiter de conversion Longint>String et vice-versa et qui de plus éviterait les inconvénients des tableaux dits dynamiques... à vérifier)
    Moi je connais un TIntegerList, mais je sais pas si c'est celle dont t'as entendu parlé

    Oui je sais je suis doué pour me faire de la pub
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  15. #15
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Merci CapJack pour ces fleurs ... Et pendant que tu étais sur la présente discussion, moi j'étais en-train de râler sur celle de la philosophie en rapport avec la richesse de Delphi à propos de l'usage du vocabulaire. Mais après tout, on peut avoir des opinions divergentes en matière de philosophie.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  16. #16
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Réponse à Sjrd / Code TIntegerList :
    Non c'est pas le code qui figure sur le site de Sourceforge (mais c'est bon de savoir pour ceux qui veulent comparer)
    Et comme j'avais dit avoir vu qq part sur ce forum et qu'il y a une fonction Chercher ... et bien je viens de le retrouver sur ce forum à l'endroit du message du 23/04/2007, 19h17 #8 où CapJack écrit "Mon source aurait peut-être sa place quelque part sur le site, ..." en y joignant le fichier téléchargeable suivant : IntegerList.pas (17,4 Ko, 11 affichages).
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  17. #17
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    Citation Envoyé par Art19
    Le probleme est que si il n'y a aucun doublon dans mon fichier et qu'il est gros (plusieurs Giga), alors je le chargerai entierement dans ma liste... ce qui signifie une grosse masse de RAM en moins sur mon ordi
    une question (la réponse ce touve dans l'aide de delphi) si tu charge un fichier de 2 GO dans un TStringlist, ce fichier sera où dans la ram ou sur DD?
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  18. #18
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Si Delphi code comme moi, LoadFromFile pointe en fait sur LoadFromStream avec comme argument un TFileStream
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  19. #19
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par Gilbert Geyer
    (Au fait il me semble avoir vu qq part sur ce forum le code d'un "TIntegerList" qui contrairement à TStringList accepte posDeb etc sans nécessiter de conversion Longint>String et vice-versa et qui de plus éviterait les inconvénients des tableaux dits dynamiques... à vérifier)
    C'est pas un que j'ai posté sur le forum par hasard ?
    Bidouilleuse Delphi

  20. #20
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par Gilbert Geyer
    message du 23/04/2007, 19h17 #8 où CapJack écrit
    Avec le lien direct c'est plus facile

    À première vue, je pense que son code est plus efficace. Faudra que je prenne le temps de le lire.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

Discussions similaires

  1. [XL-2010] Copier le contenu d'un fichier texte dans un autre fichier texte
    Par Piixx_e dans le forum Macros et VBA Excel
    Réponses: 29
    Dernier message: 15/11/2013, 11h31
  2. copier plusieurs fichiers texte dans un seul fichier texte
    Par ERICKO dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 17/08/2008, 20h21
  3. Imprimer un fichier texte sans l'afficher
    Par sheira dans le forum ASP
    Réponses: 7
    Dernier message: 13/12/2005, 12h10
  4. charger un fichier texte du disque dur
    Par frol dans le forum Langage
    Réponses: 2
    Dernier message: 02/11/2005, 17h09
  5. Fichiers texte sans accents
    Par mika dans le forum Langage
    Réponses: 5
    Dernier message: 03/11/2004, 16h42

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