Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, et autres ressources pour la rubrique C.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 08/04/2008, 16h18   #1
komput
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 39
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 39
Points : 37
Points : 37
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
komput est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2008, 17h29   #2
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 437
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 437
Points : 12 977
Points : 12 977
Quelques remarques (en commentaires) après une lecture rapide :

Code :
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 :
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)
diogene est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2008, 16h20   #3
komput
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 39
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 39
Points : 37
Points : 37
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 :
	if(fb->file == NULL) return NULL;           // perte mémoire
par
Code :
	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 :
filebuf_addm(&ma_donnee, sizeof(ma_donnee), fb)
et le tour est joué...
komput est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2008, 16h55   #4
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 437
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 437
Points : 12 977
Points : 12 977
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.
diogene est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2008, 13h10   #5
komput
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 39
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 39
Points : 37
Points : 37
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 :
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 ?
komput est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2008, 15h51   #6
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 437
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 437
Points : 12 977
Points : 12 977
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
Citation:
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.
diogene est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/04/2008, 12h55   #7
komput
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 39
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 39
Points : 37
Points : 37
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
komput est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/04/2008, 15h04   #8
Melem
Rédacteur/Modérateur
 
Avatar de Melem
 
Homme Jessee Michaël Christian Edouard
Ingénieur développement logiciels
Inscription : janvier 2006
Messages : 3 661
Détails du profil
Informations personnelles :
Nom : Homme Jessee Michaël Christian Edouard
Âge : 27
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 661
Points : 8 435
Points : 8 435
Envoyer un message via MSN à Melem
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 .
Melem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/04/2008, 14h52   #9
dapounet
Membre expérimenté
 
Avatar de dapounet
 
Étudiant
Inscription : juillet 2007
Messages : 472
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juillet 2007
Messages : 472
Points : 557
Points : 557
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
dapounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2008, 16h01   #10
komput
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 39
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 39
Points : 37
Points : 37
Citation:
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

Citation:
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...
komput est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 23h40.


 
 
 
 
Partenaires

Hébergement Web