Même si l'accès séquentiel présente bien des avantages, de nombreux flux supportent également l'accès direct, c'est à dire la capacité à accéder à n'importe quelles parties du flux dans un ordre arbitraire (en anglais : random access).
Il est ainsi possible de sauter directement à l'emplacement qui nous intéresse dans le flux à l'aide de la fonction fseek :
int fseek(FILE *flux, long decalage, int destination);
Le troisième paramètre ne peut prendre qu'une valeur parmi trois :
Mais ce ne sont pas les seules destinations possibles car le deuxième paramètre (le décalage) permet de modifier la position d'arrivée. fseek renvoie 0 en cas de succès, ou -1 en cas d'erreur.
Remarque Lorsque l'on se déplace de cette façon dans un fichier, les tampons de lecture et d'écritures doivent être vidangés. Abuser de cette technique aura donc un impact notable sur les performances.
La fonction ftell permet de connaître le nombre d'octets séparant la position actuelle du début du fichier.
long ftell(FILE *flux);
Le résultat obtenu peut donc servir de décalage dans un appel à fseek pour revenir plus tard à cette même position. Malheureusement, dans le cas de très grands fichiers, le type long ne suffira plus à exprimer toutes les positions possibles et on devra alors recourir à des fonctions plus élaborées (fgetpos et fsetpos).
Nous avons vu que l'on peut ouvrir un fichier en lecture avec "r", ou en écriture avec "w" ou "a". Il existe trois autres modes qui permettent de combiner lecture et écriture :
Remarque On ne peut pas mélanger lecture et écriture sans invalider le fonctionnement des tampons. Il est donc impératif de vidanger les tampons entre les phases de lecture et d'écriture : le moyen de plus simple est d'employer systématiquement fseek.
Image. Reprenez le programme du deuxième exercice du deuxième sujet sur les fichiers et modifiez-le pour que la fenêtre contienne seulement le quart inférieur droit de l'image. Le programme ne devra pas lire dans le fichier d'information dont il n'a pas besoin.
Censure. Écrivez un programme qui prend sur sa ligne de commande le nom et le chemin d'un fichier contenant uniquement du texte et qui remplace dans ce fichier tous les «e» par des «X». Le programme ne devra pas retenir en mémoire plus d'un caractère du fichier à la fois.
Que se passe-t-il si on modife le programme pour remplacer chaque «e» par «XXX» ?
Archive. La commande tar
est employée pour regrouper
plusieurs fichiers en un seul (sans compression). Le format employé est décrit
ici.
Écrivez un programme qui prend sur sa ligne de commande le nom et le chemin d'une archive
.tar et qui en affiche le contenu (comme la commande tar
avec
l'option t).
Désarchivage. Écrivez un programme qui prend
sur sa ligne de commande le nom et le chemin d'une archive .tar et qui la
désarchive (comme la commande tar
avec l'option x). On se limitera
à des archives ne contenant que des fichiers réguliers sans indication de chemin, et on
ne reconstituera pas les propriétés d'origine.
Matrices. On souhaite multiplier des matrices à coefficients entiers, chacune étant stockée dans un fichier contenant :
Écrire le programme qui va avec le menu suivant :
1) Saisir une matrice dans un fichier. 2) Afficher une matrice depuis un fichier. 3) Multiplier deux matrices dans un fichier.
Remarque On ne peut multiplier qu'une matrice A à n lignes, q colonnes et une matrice B à q lignes, p colonnes. On obtient alors une matrice C à n lignes, p colonnes où
Remarque Les matrices ne seront jamais «chargées» en mémoire, mais accédées à partir des fichiers.