C'est quoi un fichier?

Jennifer -  
 le père -
Bonjour,


je débute en c et pour mieux le comprendre j'aimerais savoir ce qu'est un fichier, au niveau de la mémoire :
1. est-ce un emplacement contigu de bits, d'octets, de 32 bits?
2. Le fichier peut-il ne pas être contigu?
3. Si non, comment le lancer en mémoire vive, s'il fait plusieurs Mo? (il n'y a peut être pas autant de bits juxtaposés).
4. Et d'ailleurs, comment lancer des fichiers de plusieurs Go ?
5. Est-ce que l'extension a une importance dans la mémoire ?
6. Si c'est un fichier texte, on peut accéder au second caractère en lisant le 2eme octet?
7. Ces réponses sont-elles valables indépendamment de l'OS ?
8. Mêmes questions pour les dossiers.

Merci d'avance.
A voir également:

62 réponses

le père
 
ftell n'a rien de compliqué à faire. ftell se contente de dire où en est rendu le pointeur de fichier. Il n'y a rien de sorcier là dedans, et pas besoin d'astuce particulière. C'est la moindre des choses que l'OS, qui gère l'accès eux fichiers, sache où il en est !
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Oui, mais il est obligé de lire l'intégralité du fichier pour savoir sa taille...
0
le père
 
Pas du tout. Quand tu affiches le directory, ça te met bien la taille des fichiers, tu crois qu'il les relit tous ???
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Voui, t'as raison, j'ai raisonné de travers. Je viens de vérifier la structure d'une FAT32, il y a bien à la fin du record pour chaque fichier un dword de 32 bits qui contient la taille du fichier...

En fait, je m'étais focalisé sur l'accès physique en dehors de toute struture logique.
0
le père > blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention  
 
En fait, je m'étais focalisé sur l'accès physique en dehors de toute struture logique
???. Seule la structure logique permet de savoir où se trouve la fin du fichier, l'accès physique ne le permet absolument pas.
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359 > le père
 
Je parlais de l'accès physique aux secteurs disques du fichier concerné (en dehors de la structuration qu'offre un langage qui 'offre' les données de manière séquentielle et transparente, indépendamment du media de stockage utilisé), avec lecture de leurs contenus pour y rechercher une fin de fichier...
0
le père
 
C'est bien ce que j'avais compris. Et je dis bien que cette lecture physique ne t'aide en rien à connaître la taille d'un fichier, qui est par nature une structure logique. D'où mon étonnement devant ta réponse 57.
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
J'ai imaginé (avec mon expérience) une possibilité en <53>...
0
le père
 
Dans ton 53, tu parles de chercher dans la table d'allocation, qui est une structure logique, et de rechercher un eof dans un secteur, ce qui ne correspond physiquement à rien. Il n'y a aucun marquage physique particulier à la fin d'un fichier.
Un disque (vu à travers son contrôleur, c'est bien ce qu'on appelle "l'accès physique", non ?) est constitué de paquets de taille fixe adressables par des numéros de secteur, tête et cylindre. Les notions de fichier, de table d'allocation et d'eof sont totalement inexistantes à ce niveau là.
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Il n'y a aucun marquage physique particulier à la fin d'un fichier.
Ca dépend de l'OS... certains ont une suite de car ascii (ou autre) pour indiquer justement cette fin...

Mais bon, je suis parti dans un raisonnement qui n'appartient qu'à moi, je vais avoir du mal à me rattraper aux branches ;-)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
le père
 
ça dépend de l'OS
Si tu parles du code ASCII 26 à la fin des fichiers texte (as-tu ne serait-ce qu'un seul autre exemple ?), c'est bien un marquage logique et non physique.
La notion même de marquage physique dépendant de l'OS me laisse rêveur... Il y aurait des disques spéciaux Windows, des disques spéciaux UNIX... Ne souffle pas l'idée à Bill Gates, il est capable de sauter dessus.
Mais je crois que nous papotons et que Jennifer va trouver son topic pollué quand elle reviendra ^^
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Oui effectivement, ma notion de physique n'était qu'une expression du 'bas-niveau', c'est vrai qu'aucun marquage physique ne saurait être inscrit sur les disques (à part par une suite de bits...).

Je parlais juste de la notion de séparation entre une information donnée (que j'appelle logique : 'taille du fichier' obtenue par interrogation du système de gestion de l'espace disque) et la 'vraie' information que l'on peut calculer par parcours physique des secteurs et détermination de l'EOF écrit sur disque...

J'arrête les papoteries pour l'instant :-)
0
jennifer00 Messages postés 6 Date d'inscription   Statut Membre Dernière intervention  
 
Revenons à mon problème :).
Mon but est le suivant : à partir d'un log de longue taille, je veux pouvoir accéder à la ligne d'une date précise de ce log (les dates sont en début de ligne et au format "Jan 11 00:00:00"), sans avoir à lire tout le log pour y parvenir. Si la date cherchée n'y est pas, on renvoie la date présente immédiatement plus récente. Si elle est en doublon, on renvoie la plus ancienne. On cherche les dates par dichotomie (pondérée).
Voici mon code tel qu'il est à présent (qui ne marche pas :-( ).

#include <stdio.h>
#include <string.h>
#include <time.h>

time_t string_to_time_t(char *s)
{
time_t rawtime;
struct tm * timeinfo;
char month_s[4] ;
int month,day,hour,minute,second;
sscanf(s, "%3s %d %d:%d:%d", month_s, &day, &hour, &minute, &second);

char * month_names[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int i=0;
while( strcmp(month_s,month_names[i]) != 0 )
i++;
month=i;

time (&rawtime);
timeinfo=localtime(&rawtime);
timeinfo->tm_mon=month;
timeinfo->tm_mday=day;
timeinfo->tm_hour=hour;
timeinfo->tm_min=minute;
timeinfo->tm_sec=second;
return mktime(timeinfo);
}

time_t get_date(FILE *fp)
{
char s[16];
return string_to_time_t(fgets(s,16,fp));
}

int goto_nextline(FILE *fp)
{
int c; //EOF is a int
do c=fgetc(fp) ;
while ((c != '\n') && (c !=EOF));
if (c=='\n')
return 0;
else
return 1;
}


void goto_beginning_of_line(FILE *fp)
{
int c;
if (ftell(fp) !=0)
{
fseek(fp,1,SEEK_CUR);
do
{
fseek(fp,-2,SEEK_CUR);
c=fgetc(fp);
}
while ( ftell(fp)-2>=0 && c != '\n' );
if( ftell(fp)==1 )
fseek(fp,-1,SEEK_CUR);
}
}

int search_date(FILE *fp, time_t time)
{
FILE *fpmin, *fpmax, *fptmp;
time_t timemin, timemax;
fpos_t pos;
fpmin=fpmax=fptmp=fp;
fseek(fpmin,0,SEEK_SET);
fseek(fpmax,0,SEEK_END);
fseek(fptmp,0,SEEK_SET);
timemin=get_date(fpmin);
goto_beginning_of_line(fpmax);
timemax=get_date(fpmax);
fgetpos(fpmin,&pos);
while(goto_nextline(fpmin)==0 && get_date(fpmin)<time)
{
fsetpos(fpmin,&pos);
fsetpos(fptmp,&pos);
float weight=(float)(time-timemin)/(float)(timemax-timemin);
long difference=ftell(fpmax)-ftell(fpmin);
fseek(fptmp,(long) weight * difference,SEEK_CUR);
goto_beginning_of_line(fptmp);
if (time < get_date(fptmp))
{
fpmax=fptmp;
timemax=get_date(fpmax);
}
else
{
fpmin=fptmp;
timemin=get_date(fpmin);
fgetpos(fpmin,&pos);
}
}
fp=fpmin;
return 0;
}

int main(int argc, char **argv)
{
FILE *fp=fopen("log.txt","r");
if (fp==NULL)
fprintf(stderr,"File can't be opened\n");
else
{
time_t time=string_to_time_t("Dec 11 12:00:00");
search_date(fp,time);
//faire des choses ici
}
fclose(fp);
return 0;
}

J'ai besoin de votre aide pour faire marcher ce programme (j'ai un segmentation fault pour l'instant).
Voilà, merci d'avance.
0
heyquem Messages postés 759 Date d'inscription   Statut Membre Dernière intervention   131
 
Jennifer, peux tu nous dire pourquoi tu veux faire ta recherche par dichotomie:
- la méthode par dichotomie est-elle stipulée par un devoir ?
- t’es tu fixée toi-même cette méthode à titre d’exercice ?
- est-ce par choix en pensant que c’est la meilleure méthode ?


Car je le redis: pour ma part , je pense que ce n’est pas la bonne méthode à appliquer.

Une dichotomie se justifie me semble-t-il quand ce qui est recherché est susceptible de se trouver aléatoirement n’importe où. Je ne pense pas que ta date soit vraiment n’importe où dans le fichier.


De plus, une dichotomie, pratiquement, en programme , ça veut dire: je fixe une borne, je parcours un intervalle, je fixe une borne, je parcours un intervalle, etc. J’ai l’impression que ça n’a aucun sens de faire ça par programme. Pourquoi faire interrompre le programme dans son exploration d’un intervalle pour pouvoir lui spécifier “ah, maintenant, tu changes d’intervalle“

Plus précisément, considérons un intervale de 1 à 50.
Soit tu lui dis: parcours [1,25]. Si tu ne trouves pas, parcours [25,50]
mais pourquoi diable le faire arrêter pour lui spécifier qu’après [1,25], il va devoir parcourir [25,50] si il n’a pas trouvé ?????
Inversement, si tu lui dit d’abord : parcours [25,50], et si tu ne trouves pas parcours [1,25]; tu obliges le programme à aller dans la deuxième moitié, et ensuite de revenir en arrière dans le fichier pour explorer la première moitié.

Pour moi, c’est des danses d’indiens autour d’un totem au lieu de planter directement la hache dans le totem.


Et quand je vois la complication de ton code, je me dis qu’on n’est pas verni quand on pratique le C++ ou le C. En Python, ta recherche prend 3 lignes. S’il faut passer 2 semaines pour rechercher une date dans un fichier, eh ben dis donc. Mais bon, moi aussi je veux apprendre le C et je pense que je mettrai aussi 2 semaines pour écrire cette recherche.


Ugh.
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
La dichotomie est séduisante si l'accès aux données est direct, elle ne présente pas (trop) d'intérêt dans le cas contraire.
0
le père
 
Je n'ai pas tout cherché à comprendre, mais je vois des chose choquantes...
fpmin=fpmax=fptmp=fp;
Tu recopies la valeur de fp dans plusieurs autres variables
Mais fp, c'est un pointeur, c'est à dire l'adresse d'une zone de la mémoire. Quand tu 'te promènes' dans le fichier, le contenu de la structure pointée par fp varie, mais cette structure reste à la même adresse en mémoire. Donc fp ne change jamais tant que tu ne refais pas de fopen.
Donc fpmin, fpmax etc restent eux aussi toujours égaux à fp
tes
fseek(fpmin,0,SEEK_SET);
fseek(fpmax,0,SEEK_END);
fseek(fptmp,0,SEEK_SET);
agissent tous sur le même fichier !
0
le père
 
agissent tous sur le même fichier
je veux dire sur le même descripteur de fichier, celui pointé par fp
0
heyquem Messages postés 759 Date d'inscription   Statut Membre Dernière intervention   131
 
Qu’est ce que ça veut dire “accès direct aux données “ ?
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
que tu peux récupérer directement le contenu de la 25ième ligne ou de la 75ième...
0
jennifer00 Messages postés 6 Date d'inscription   Statut Membre Dernière intervention  
 
heyquem, les dates du log sont évidemment triées (la plus récente en dernier, les lignes sont écrites au fur et à mesure). Ainsi je n'ai pas besoin de tout parcourir, je prends une date au "milieu" du fichier (en fait j'utilise un barycentre, mais peu importe, ça ne change rien). Par comparaison, je n'aurais plus qu'une moitié de fichier à traiter, et ainsi de suite. Je ne vais donc pas chercher [0,25] puis [25,50], c'est soit l'un, soit l'autre.
blux, le fait que j'utilise fseek implique que l'accès aux données est direct, non?
le père, je veux effectivement qu'ils agissent tous sur le même fichier, mais avec des indices différents (l'un qui sera la borne supérieure, l'autre la borne inférieure, et un troisième temporaire pour des raisons pratiques).
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
blux, le fait que j'utilise fseek implique que l'accès aux données est direct, non?
Tu lis une série de caractères à partir d'une position dans le fichier, mais encore faut-il que ton positionnement soit sur le premier caractère de la date... c'est-à-dire que tes lignes aient la même taille...

ou alors je me trompe...
0
le père > blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention  
 
on pourrait appeler ça un accès semi-direct.
Car si on ne sait pas sauter directement à un début de ligne, on peut quand même le trouver sans faire une lecture complètement séquentielle
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359 > le père
 
C'est le principe du 'séquentiel indexé' : un pointeur qui donne l'accès au secteur qui contient la donnée, et après accès au secteur concerné, parcours séquentiel du secteur pour trouver l'enregistrement recherché...
0
le père
 
le père, je veux effectivement qu'ils agissent tous sur le même fichier, mais avec des indices différents (l'un qui sera la borne supérieure, l'autre la borne inférieure, et un troisième temporaire pour des raisons pratiques).
Je sais bien, c'est pour ça que j'ai rajouté le message 71. Tu travailles toujours sur le même indice car tes différentes copies du pointeur pointent toutes sur la même zone de mémoire.
As-tu essayé, après avoir fait
fseek(fpmin,0,SEEK_SET);
fseek(fpmax,0,SEEK_END);
de comparer ftell(fpmin) et ftell(fpmax) ?
0
heyquem Messages postés 759 Date d'inscription   Statut Membre Dernière intervention   131
 
« Que tu peux récupérer directement le contenu de la 25ième ligne ou de la 75ième... »


Oui, mais qu’est ce que ça veut dire «récupérer directement » ?

Et qu’est ce que ça veut dire «25ième ligne» tant que les données ne sont pas dans une structure de données telle qu’une liste pour laquelle l’expression «25ième ligne» ait un sens; structure de données qui, pour être créée (en mémoire vive) demande une lecture du fichier (en disque dur), lecture signifiant que ce qui est lu n’est pas connu avant que d’être lu........
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Si les lignes sont de longueur constante, alors on peut aller au début de la n-ième ligne en se positionnant au ((n-1) x (taille de la ligne)) + 1) ième caractère avec un fseek...
0
jennifer00 Messages postés 6 Date d'inscription   Statut Membre Dernière intervention  
 
Elles ne le sont pas :(
0
jennifer00 Messages postés 6 Date d'inscription   Statut Membre Dernière intervention  
 
Le père, ce que tu veux dire, c'est que je dois ajouter un petit '&' devant chaque nom ?
&fpmin=&fpmax=&fptmp=&fp;
c'est bon là?
0
le père
 
Non, d'ailleurs faire &variable=&autrevariable ne veut rien dire en C et serait rejeté par le compilateur. & a un sens bien précis en C, ce n'est pas un remède magique qu'on essaye à tout hasard dans les cas graves :)

Ce que je dis c'est que tes différentes variables pointeur contiennent toutes la même adresse. Donc, que tu fasses fseek ou fgetc avec l'un ou l'autre des pointeurs, c'est toujours sur la même zone de mémoire que tu agis.
fseek et fgetc ne modifient pas fp (comment le pourraient-il ?) donc fp reste constant après le fopen et en prendre des copies ne t'avance pas à grand chose. Ce qui évolue, c'est la zone mémoire pointée par fp, mais j'ai l'impression que la distinction n'est pas très claire pour toi.
0
heyquem Messages postés 759 Date d'inscription   Statut Membre Dernière intervention   131
 
« à moins d'avoir des 'lignes' de taille fixe, tu ne peux envisager un positionnement direct à la n-ième ligne dans un fichier 'séquentiel'. »
dans le 45

« La dichotomie est séduisante si l'accès aux données est direct, »
dans le 69

« Si les lignes sont de longueur constante, »
dans le 80


Blux, on n’est pas censé savoir que dans le post 69 tu te places dans le cas de figure décrit dans le 45 sans que tu le précises.

L’absence de précision dans le 69 tend à faire penser que tu y parles de la manière (materielle ou algorithmique) d’accéder à des données, pas de la façon dont elles sont structurées.
0
blux Messages postés 27121 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Blux, on n’est pas censé savoir que dans le post 69 tu te places dans le cas de figure décrit dans le 45 sans que tu le précises.
Non, ma remarque est valable même si les données ne sont pas identiques.
Une recherche dichotomique est séduisante quand on peut aller chercher la n-ième donnée, si on doit tout parcourir pour aller se positionner au milieu de l'intervalle choisi, alors cette dichotomie perd son charme...

L’absence de précision dans le 69 tend à faire penser que tu y parles de la manière (materielle ou algorithmique) d’accéder à des données, pas de la façon dont elles sont structurées.
J'ai bien écrit : si l'accès aux données est direct, je pense que c'est assez précis, non ? ;-)
0
jennifer00 Messages postés 6 Date d'inscription   Statut Membre Dernière intervention  
 
Le père: Alors, qu'est-ce que vous proposez pour remédier à cette erreur?
0
le père
 
Je propose que tu exécutes ton programme en pas à pas pour nous dire où a lieu l'erreur
0
ummite
 
un fichier c'est un jolie truc fait avec du binaire ^^
0