Bonjour les amis du forum de programmation de l´excellent site web de JV.com!
Quelqu´un pourrait m´expliquer comment lire un fichier binnaire en acces direct ?
avec l´aide de fread()
sans toutefois utiliser while(!eof(Fichier))!
de vos commentaire
en passant Nick a une coupe de cheveaux sexy =)
alors, c´est simple :
d´abord, tu ouvre ton fichier :
FILE *fichier = fopen("monfichier.bin","rb");
on met rb pour lire en binaire(en pratique, je sais pas trop ce que ca change)
ensuite, tu recupere la position de fin de ton fichier :
fseek(fichier, 0, SEEK_END);
int end = ftell(fichier);
ftell permet de recuperer la position actuelle dans le fichier
ensuite, tu reviens au debut :
fseek(fichier, 0, SEEK_SET);
tu fais ta boucle de lecture :
while(ftell(fichier)<end)
{
tu met ce que tu as besoin pour lire :
char mavar;
fread(&mavar,1,1,fichier);
les 2 paramettres du milieu sont la taille que tu lit : ici, 1*1 octet.
pour un int, c´est 4 octet, tu met donc
int mavar;
fread(&mavar,4,1,fichier);
puis, tu ferme ta boucle :
}
voila, c´est simple
delfare
j´ajouterais que tu peux ranger le binaire dans un char*
Tu te sers de la variable int end définie par Dnob ci dessus.
Tu fais juste un :
char* buf = (char*)malloc(end);
puis :
fread(buf,end,1,fichier);
Voila, a partir de la, ton fichier est entierement en RAM, sans while. tu n´as plus qu´a faire fclose et puis tu roules
Si tu veux réécrire, tu fais pareil avec fwrite.
mais est-ce qu´il existe une fonction qui peut me permettre de savoir la taille du fichier par exemple dans mon cour de VB.net : LOF(#fichier)/structure de l´enregistrement
ok mais si je veux lire de le fichier de bas en haut ?
"mais est-ce qu´il existe une fonction qui peut me permettre de savoir la taille du fichier"
--> en C, c´est + une astuce : Dnob te l´a dit :
fseek(fichier, 0, SEEK_END); // place le curseur
de lecture a la fin du fichier
int end = ftell(fichier); // te dit ou est le cur
seur
--> donc tu as la taille ici ! c´est la variable end de Dnob !
"ok mais si je veux lire de le fichier de bas en haut ? "
--> Les disques durs sont optimisés pour une lecture séquentielle -> de "haut en bas".
Donc typiquement, il n´est pas conseillé de les lire autrement.
Tu as quand meme la commande fseek qui te permet de déplacer le curseur de lecture, rien ne t´empeche de le faire "monter", et de lire chaque octet, mais tu perds en vitesse d´acces.
La solution que je te propose plus haut, c´est de copier entierement le fichier en RAM, dans un tableau de char.
Ensuite, tu en fais ce que tu veux, en acces aléatoire (manip de tableau).
Il y a des primitives UNIX et windows qui permettent de connaitre la taille d´un fichier...
mais peut etre faut il faire attention aux sparses file.
Mapper le fichier en mémoire pourquoi pas (mmap/munmap mais je ne suis pas sur de la compatibilité windows). Mais je déconseille fortement la copie en mémoire, c´est assez consomateur en ressource...
je déconseille également les mmap/munmap, mais je maintiens que la copie en mémoire peut apporter.
(apres tout dépend ce que tu fais)
En effet, au niveau ressources, ça demande d´allouer la taille du fichier en RAM, mais derriere, les opérations que tu fais vont a grande vitesse.
Au boulot, je fais des parsers de fichiers CFAO : ça peut etre tres gros, mais surtout calculatoire.
En accédant directement sur le disque, le fichiers met un temps incroyable a se traiter, alors que si on le monte en RAM, ça va bien plus vite.
Evidemment, apres, si le fichier est énorme, on monte des parties de celui ci, et non pas le fichier entier, mais c´est + complexe.
C´est toujours le meme dilemne :
-> temps VS utilisation mémoire.
Apres, évidemment, qu´est ce que l´auteur de ce topic veut faire ? quelle taille de fichier veut il traiter ?
mmm, en effet si tu as besoin d´un access aléatoire sur le fichier, il est préférable de le monter en mémoire, je pensais qu´il voulait quand meme le traiter séquentielement.
Ah vi, s´il veut le traiter séquentiellement, la lecture directe est envisageable.
Mais tu n´as pas tout lu Godrik, lol :
francis8 > "ok mais si je veux lire de le fichier de bas en haut "
![]()
ah, pris en flag.
je fais comme mes etudiants, je lis pas tout! ![]()
lol ! ça m´arrive souvent aussi de ne pas tout lire ![]()
"comme mes etudiants"
Tu enseignes quoi et a qui Godrik ?
bien merci quand meme de vos réponses les gars, mais hier soir j´ai finalement tomber sur le bon code...
c´est un peu le meme principe que VB.NET pour trouver le nombres d´enregistrements dans le fichier
LOF(fichier)/structure
Voici mon code pour lire un fichier binaire à l´inverse:
fseek(fBinaire, 0, SEEK_END);
iLongueur = (ftell(fBinaire))/sizeof(ENREMPLOYE);
iCompteur=0;
while(iCompteur != iLongueur)
{
iCompteur++;
fseek(fBinaire, -(iCompteur)*(int)sizeof(ENREMPLOYE), SEEK_END);
fread(&eEmploye,sizeof(ENREMPLOYE),1,fBinaire);
printf("%d,%s,%c,%d,%.2lf\n",eEmploye.iCode,eEmp
loye.sNom,eEmploye.cSexe,eEmploye.iExperience,eEmp
loye.dTauxHoraire);
}
Merci encore de vos réponses ...bien sympas! ![]()
Fvirtman =>
Aller....rigole pas de moi c´est la premiere fois que j´utilise les fichiers binaire....mon professeur nous a seulement lancer quelques feuilles sur notre guelle et nous mettre sur notre propre sort ...
![]()
oops je viens de me rendre compte que moi aussi jai pas tout lu ... ![]()
"oops je viens de me rendre compte que moi aussi jai pas tout lu ... "
--> Tout a fait !
On t´a proposé ici 200 alternatives a cette méthode lente que tu postes avec le while.
La seule chose pseudo intéressante dans ton code est le ENREMPLOYE.
Cependant, un cast du tableau globale de réception suffit a ne pas s´emmerder avec ça
Enfin bref !
j´enseigne la base de données (algebre, sql, transaction, conception, normalisation) aux étudiant de l´ENSIMAG. Je devrais faire plus dans le camboui d´ici peu, unix, systeme, reseau... Ca me change les idées le camboui!
Pour en revenir au probleme de base.
Je conjecture fortement que le code fournit est EXTREMENT lent.
En effet, tu es en PERMANENCE entrain de replacer les tetes de lectures de ton disque dur.
Tu pourrais au moins en lire plusieurs d´un coup ca semblerait moins gore...