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 :

Ecriture fichier binaire et vitesse


Sujet :

C

  1. #1
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut Ecriture fichier binaire et vitesse
    Bonjour,

    J'ecrit de gros fichiers binaires (qq 10GO) avec les fonctions classique fopen, fwrite...
    J'ai remarqué un gros gain en vitesse significatif (30%°, en augmentant la taille du buffer en utilisant la fonction
    setvbuf(f,NULL,_IOFBF,262144)

    Comment ajuster la taille du buffer, y a t-il une limite, et quel est le risque.

    merci de vos suggestions

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Mes connaissances ne sont pas parfaites sur le sujet, donc il est possible que je me trompe ou que j'ignore certains aspect du problème.

    Le principe du buffer est de diminuer les accès au disque en stockant les données à écrire dans le buffer et à les écrire quand le buffer est plein.

    Ainsi si on veut écrire 20 octets, au lieu d'accéder 20 fois au disque pour écrire à chaque fois 1 seul octet, on y accède une seule fois pour écrire 20 octets.

    Il faut aussi savoir que l'ordinateur ne sait pas écrire (et lire) un seul octet sur le disque (?), il va réécrire tout le secteur qui peut faire 512kio par exemple.

    La taille optimale de buffer est donc, je pense, la taille d'un secteur du disque lu (?). Pour la limite, il y en a obligatoirement une, mais je pense qu'elle est suffisamment grande pour qu'on ai pas à s'en soucier. Après, si la taille du buffer est supérieur à la taille d'un secteur (?) on ne gagnera rien.

    Le seul risque que je verrais c'est de perdre en performances lors de la lecture ou le gaspillage de mémoire.

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Le seul risque que je verrais c'est de perdre en performances lors de la lecture ou le gaspillage de mémoire.
    Si l'on veut vraiment chipoter, on peut ajouter le fait que plus de données risquent d'être perdues en cas de crash de la machine ou de plantage du programme. 262144 octets, ça fait quand même 256 Kio.

    Cela dit, c'est difficile de mesurer cela car il faut les mettre en balance avec les mémoire cache utilisées par le système d'exploitation ainsi que par le disque dur lui-même. Donc, c'est au cas par cas, et en examinant également ce que fait le programme.

  4. #4
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Merci de vos remarques.
    Effectivement ca dépend bien systeme. Aucun effet observé sur Linux à contrario de windows.

  5. #5
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Lors de la lecture de ton fichier avec fread et l'écriture avec fwrite...
    Le seul conseil précis et supplémentaire (les précédents sont déjà très bons) :
    Evite d'avoir un buffer malloqué/free tout le temps !

    Garde bien un "char buf[BUF_LEN]" en variable qui sera du coup alloué en "dur" dans l'exécutable, et t'évitera de faire trop d'appels à malloc... (c'est la méthode qui était utilisée il y a très très très longtemps pour les traitements répétitifs).
    Si tu fais un seul malloc au tout début, c'est pas gênant.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  6. #6
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    peux-tu etre plus explicite à propos de ton buffer de char. Pour ma part je lis des doubles

  7. #7
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Outch... lire des doubles est peut être risqué car considérés comme nombres signés (et même flottants)... donc tu "peux" avoir des traitements FPU nécessaires pour rien (et ceux là sont les plus lourds de tous).
    Donc pas de traitement de chaînes de caractères possibles (si on respecte strictement le typage)...

    Même si tu lis en binaire, ton fichier est constitué de caractères (char sur UNIX/Linux et _tchar sur Windows pour être "indépendant" de l'encodage choisit à la compilation), donc un tableau de char/_tchar est logique !

    Il n'y a pas de code, mais cela m'intéresse de voir comment et pourquoi tu lis des "double" quand il s'agit d'écrire des fichiers, de plusieurs Go qui plus est !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  8. #8
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    En fait c'est un peu plus complexe, j'écris des float à partir de donnée d'un énorme tableau de double (quelques GO, voir 10GO). Mais sinon c'est trivial !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    float cor3[7];
    // ipt peut valoir plusieur millards
          for (i=0;i<ipt;i++) {
            cor3[0]=(float)cord[i*6];
            cor3[1]=(float)cord[i*6+1];
            cor3[2]=(float)cord[i*6+2];
            cor3[3]=(float)cord[i*6+3];
            cor3[4]=(float)cord[i*6+4];
            cor3[5]=(float)cord[i*6+5];
            cor3[6]=(float)loss[i];
            fwrite(&cor3,sizeof(float),7,f0);
         }

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    En fait c'est un peu plus complexe, j'écris des float à partir de donnée d'un énorme tableau de double (quelques GO, voir 10GO). Mais sinon c'est trivial !
    As-tu envisagé mmap() ?

  10. #10
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Non, mais pour avoir déjà regardé ca, j'avoue que cela m'apparait un peu obscur. Aurais-tu un example simple?

  11. #11
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Hmmmm... et je suppose qu'il y a un read sur le même fichier plus tard pour reconstruire le tableau ?

    Cela implique d'énormes problèmes si on ne reste pas sur la même architecture... voire la même machine avec le même OS !
    Je m'explique : vous devez connaitre le principe d'endianess (comment représenter les poids forts des poids faibles).
    Si jamais vous envoyez un fichier écrit par un système big endian vers un système little endian, vous risquez d'avoir des valeurs totalement différentes...
    C'est une des raisons pour le fameux itoa/atoi et plus techniquement en réseau : hton et ntoh.

    Tant que cela reste sur les mêmes machines ça va, mais sinon, il faudrait convertir chaque ligne du tableau en ascii, puis écrire l'ascii... et faire l'inverse de l'autre côté.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  12. #12
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Oui il a un read, mais dans un autre code. Et finallement, l'ecriture et la lecture sont nécessairement sur la même machine.

  13. #13
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Je pencherai pour un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    float *tab = NULL;
    int fd;
     
    fd = open("myfile.txt");
    tab = mmap(NULL, size de votre float, PROT_READ, MAP_PRIVATE, fd, 0);
    /* MAP_PRIVATE ne partagera avec aucun fork ou thread si j'ai bien compris */
    /* 0 indique que le tableau démarre dès le 1er caractère du fichier */

    EDIT : Mais du coup, ma remarque du buffer de char est inutile !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    Non, mais pour avoir déjà regardé ca, j'avoue que cela m'apparait un peu obscur. Aurais-tu un example simple?
    Pas sous le coude (il faudrait en écrire un) mais le principe est assez simple : mmap() projette le contenu d'un fichier en mémoire.

    Pour ce faire, le système va utiliser les mécanismes de la mémoire virtuelle : il va te faire croire que le fichier est entièrement chargé en mémoire et va ne charger les pages nécessaires que lorsque tu essaieras d'y accéder. Par contre, pour toi, ce sera complètement transparent. Tu pourras considérer ton fichier comme entièrement chargé en mémoire et te passer complètement d'appels aux I/O. Et l'avantage, c'est que ça fonctionne dans les deux sens (en écriture comme en lecture).

    Ce n'est pas spécialement pratique pour les fichiers texte (il faut retrouver soi-même la chaîne et son délimiteur) mais c'est idéal pour les fichiers binaires, puisque tu n'as qu'à les écrire naturellement en mémoire plutôt que faire des write de la taille d'un double ou d'un float.

    Ça veut dire également que tu délègues au système la tâche de gérer les transferts entre le disque et la mémoire et que tu le laisses donc choisir la taille optimale de ses buffers, et tu lui permets d'organiser son travail en fonction de la charge des autres processus.

    Le seul inconvénient du mapping de fichier est que, par nature, le fichier doit pouvoir être mappé, ce qui lui impose en pratique d'être un fichier régulier sur un disque ou assimilé. Tu ne pourrais pas traiter l'entrée standard de cette façon, par exemple, ni renvoyer la sortie vers un tube nommé ou autres artifices.

  15. #15
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Merci de l'example mais qui génére systéméatiquement à la compilation "Invalide conversion void* to float*

    Cela dit, j'ai fais quelques recherches sur le web et j'ai trouvé des example plus complet mais sur le même format et qui génére aussi la même erreur.

    Là je suis sec

  16. #16
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Euuuuh...
    Et avec ce compilateur, si vous tapez simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <unistd.h>
    #include <stdlib.h>
     
    int maint(void)
    {
      float *test;
     
      test = malloc(sizeof (float));
      return (0);
    }
    Ca compile ?.... parce que ça fait très très bizarre X_x

    EDIT : avec quel compilo compilez-vous vos programmes ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  17. #17
    Membre confirmé
    Inscrit en
    Janvier 2009
    Messages
    598
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 598
    Points : 628
    Points
    628
    Par défaut
    Salut,
    Je n'ai jamais utilisé l'assembleur avec le C mais si cela peut t'aider il y a une instruction d'écriture de bloc binaires en assembleur, et idem en lecture, qui permettent d'écrire/lire les données en bloc et non une à une.
    Ah pardon je suis à coté de la plaque, je m'en vais dormir
    Cliquez ici et reprenez le pouvoir !
    A bas IE !, Google, et le pistage du net, testons DuckDuckGo.com
    Lords Of The Realm II Download : Lords of the realm 2
    Infos en anglais :Ici

  18. #18
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    gcc, ok j'ai trouvé il faut même (float *) devant mmap

  19. #19
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Bizarre de devoir faire un cast explicite avec du void*...

    gcc avec des flags spéciaux ?

    Mais si ça fonctionne, c'est déjà positif...
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  20. #20
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    gcc, ok j'ai trouvé il faut même (float *) devant mmap
    Citation Envoyé par Metalman Voir le message
    Bizarre de devoir faire un cast explicite avec du void*...
    Normal, un pointeur sur n'importe quoi peut se transformer automatiquement en void *

    Par contre, l'inverse n'est pas vrai, un pointeur void * (le retour de mmap) doit est casté explicitement en pointeur sur objet.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

Discussions similaires

  1. Ecriture fichier binaire
    Par Thedahu dans le forum Général Python
    Réponses: 9
    Dernier message: 10/06/2013, 14h46
  2. Lecture et ecriture fichier binaire
    Par gedonet dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 20/04/2009, 19h51
  3. lecture ecriture fichier binaire
    Par jonckers dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/04/2007, 09h12
  4. Ecriture fichier binaire : Format TIFF
    Par xChRiSx dans le forum C++
    Réponses: 2
    Dernier message: 12/04/2007, 18h39
  5. [LG]ecriture dans un fichier binaire
    Par jsaviola dans le forum Langage
    Réponses: 3
    Dernier message: 26/12/2003, 17h30

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