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

Contribuez Discussion :

Buffer E/S rapide pour fichier [Sources]


Sujet :

Contribuez

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 39
    Points : 47
    Points
    47
    Par défaut Buffer E/S rapide pour fichier
    Bonjour !

    Dans certaines applications qui doivent charger, interpréter, écrire des fichiers, les opérations de lecture/écriture prennent parfois beaucoup de temps si on écrit caractère par caractère par exemple.
    J'ai donc progammé une bibliothèque de fonctions de lecture/écriture dans des fichiers, avec un buffer. Par exemple dans le cas de l'importation d'un fichier WAV avec traitement et écriture à la volée, j'ai diminué le temps d'exécution par 4.

    Je donne les sources ici, c'est une archive 7-zip.

    Je me demande quand même si ce que j'ai fait n'existe pas déjà dans des librairies +/- standard, c'est quand même pratique.

    J'ai créé 2 structures de données, une pour le buffer en lecture et une pour le buffer en écriture. Principalement parce que c'est beaucoup plus facile comme ça plutôt que de faire un unique type de buffer qui fonctionnerait en lecture et en écriture, et qui aussi consommerait un peu plus de CPU. Enfin ça viendra peut-être, mais pour l'instant moi je n'en ai pas besoin...

    Les fonctions disponibles sont :
    - écriture/lecture d'un unique caractère
    - écriture/lecture d'une plage entière
    - positionnement à un endroit particulier dans le fichier
    - récupérer la position courante

  2. #2
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Quelques remarques (en commentaires) après une lecture rapide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    filebufw *filebuf_openw(char *nom, int param, int size) {
    	filebufw *fb;
    	if((fb=malloc(sizeof(*fb))) == NULL) return NULL;
    	fb->file = fopen(nom, (param ? "wb+":"wb"));
    	if(fb->file == NULL) return NULL;           // perte mémoire
    ....
    idem dans filebufr *filebuf_openr(char *nom, int size)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int filebuf_addm(void *ptr, int size, filebufw *fb) {
    ....
    	ptr+=towrite; ....                         //ptr est void *
    idem dans filebuf_popm(void *ptr, int size, filebufr *fb)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 39
    Points : 47
    Points
    47
    Par défaut
    Bonjour !

    En effet diogene, je m'étais aperçu de la perte de mémoire mais je n'avais pas internet pendant ces vacances alors je n'ai pas encore actualisé le code. Je crois bien que j'ai aussi fait une ou deux retouches plus esthétiques qu'autre chose, en tout cas ce sera dans le nouveau code. Je préviendrai quand il sera disponible.

    Remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	if(fb->file == NULL) return NULL;           // perte mémoire
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	if(fb->file == NULL) {free(fb); return NULL;}
    Mais pour le void* moi j'aime bien parce que ça évite les warnings du compilateur. Je veux dire, la fonction n'est pas faite pour écrire des char* uniquement, mais n'importe quelle donnée.

    Si on veut écrire des données int ou double ou n'importe quelle structure exotique on met tranquilement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    filebuf_addm(&ma_donnee, sizeof(ma_donnee), fb)
    et le tour est joué...

  4. #4
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Le passage d'un void * en paramètre est logique. C'est l'incrément du void *,qui me gène :
    Du fait que le type (donc la taille) de l'objet pointé est inconnu, de combien sera incrémenté ptr ? En bonne logique, ce devrait être interdit.
    J'ai testé sur 2 compilateurs. Le premier me donne une erreur et le second un warning (ce qui est le moins qu'on puisse attendre).
    Je n'ai pas trouvé de comportement clairement défini dans la norme sur la question de l'arithmétique mettant en cause un pointeur sur void.

    Pour ces raisons, j'éviterais ce genre d'écriture.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 39
    Points : 47
    Points
    47
    Par défaut
    J'ai actualisé les sources avec les modifications que j'ai indiquées dans mon dernier post.
    Je donne les sources ici, c'est une archive 7-zip.

    Pourtant, je n'ai aucune erreur ni aucun warning de compilation (avec mingw sous windows) alors je ne me suis pas préoccupé du tout de la manipulation du void*. Peux-tu indiquer les compilateurs que tu as utilisé ?

    En tout cas si on fait comme ça le problème doit être réglé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptr=(char*)ptr+towrite;
    Je vais me documenter un peu avant de faire la modif dans le code. En tout cas il y a plusieurs endroits à modifier.

    Mais quand même, vu que l'unité élémentaire de mémoire c'est l'octet, mon void* pointe vers un certain octet, alors en incrémentant de N on va aller N octets plus loin... et comme sizeof() renvoie un nombre d'octets, tout le monde doit être content ! en fait je ne vois pas trop comment il faut se représenter ce fameux void* si tu dis que ça pose problème... pour moi c'est de le transtyper en char* qui n'est pas logique parce que la nature des données manipulées on s'en moque pas mal.

    Est-ce que tu peux expliquer ? et dire dire ce qui ne va pas dans mon avis ?

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Un compilateur Borland (Builder 6) indiquait une erreur. Mingw émettait un warning. Ca doit dépendre des options de warnings à la compilation si le tien était muet sur le sujet.
    Pour info, l'unité de mémoire est le byte (qui correspond souvent à un octet).

    La norme dit
    A pointer to void shall have the same representation and alignment requirements as a pointer to a character type
    Mais elle ne dit pas (ou du moins je ne sais pas où) que l'arithmétique des void* est celle des char*.

    Normalement, incrémenter un pointeur augmente l'adresse concernée du nombre de bytes égal à la taille de l'objet pointé. Dans le cas de void *, cette taille est inconnue et on ne devrait pas faire d'arithmétique sur ces pointeurs (ni les déréférencer). C'est leur différence par rapport à un char*.

    A ta place, j'opérerais un transtypage tant que ce point est incertain.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 39
    Points : 47
    Points
    47
    Par défaut
    Aah bah si c'est la norme qui le dit
    J'ai mis à jour le code, toujours dispo ici en archive 7-zip.

    Mais quand je compile j'active TOUS les warnings pourtant (-Wall), sous MingW et rien n'apparaît à ce sujet. J'ai une version plutôt récente de MingW, celle incluse dans CodeBlocks 8.02

  8. #8
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par komput Voir le message
    J'ai une version plutôt récente de MingW, celle incluse dans CodeBlocks 8.02
    Et qui est la même que celle incluse depuis C:B 1.0 .

  9. #9
    Membre confirmé Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Points : 567
    Points
    567
    Par défaut
    Citation Envoyé par komput Voir le message
    Je me demande quand même si ce que j'ai fait n'existe pas déjà dans des librairies +/- standard, c'est quand même pratique.
    Il y a les fonctions setbuf() et setvbuf().
    :wq

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 39
    Points : 47
    Points
    47
    Par défaut
    Et qui est la même que celle incluse depuis C:B 1.0 .
    moi qui pensais qu'ils suivaient un minimum, je vais regarder ça

    Il y a les fonctions setbuf() et setvbuf().
    Oui, mais j'ai fait l'essai sur ma machine et ça marche pas. Je veux dire mon petit code est toujours 2-3 fois plus rapide quand j'écris caractère par caractère. Je ne l'ai toujours pas testé sous linux, ma machine a trop de mal. Mais si vous avez des chiffres, c'est toujours bienvenu...

Discussions similaires

  1. [Bash] et [Perl] - le plus rapide pour parcourir un fichier ?
    Par Bahan_auboulot dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 23/12/2008, 10h46
  2. Réponses: 4
    Dernier message: 30/04/2005, 13h59
  3. buffer pour fichier
    Par Bug's Bunny dans le forum C
    Réponses: 6
    Dernier message: 11/06/2004, 13h21
  4. [Kylix] Composant IBM pour fichiers XML
    Par Mister Nono dans le forum EDI
    Réponses: 1
    Dernier message: 29/09/2002, 20h28

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