:: Enseignements :: Licence :: L2 :: 2011-2012 :: Système ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Entrées/Sorties |
Le but de ce TP est d'utiliser les principales fonctions de manipulation
d'entrées/sorties en C de la bibliothèque standard afin d'illustrer les
notions de tampons d'entrées/sorties.
Exercice 1 - Copie élémentaire
On commence ce TD par mettre en place un environnement de travail propre :
- créer un nouveau répertoire ;
- télécharger le fichier copy1.c ;
- écrire un Makefile pour compiler copy1.c en un programme copy1.
Essayer par exemple
./copy1 < foo
avec un fichier texte
foo arbitraire.
Exercice 2 - Effet des tampons
Pour pouvoir expérimenter l'efficacité des tampons de fichiers, nous voulons :
- mesurer le temps d'exécution des lectures/écritures ;
- faire des mesures sur des fichiers de tailles variables.
-
Mesures de temps :
Modifier le programme copy1.c pour qu'il imprime sur stderr
le temps d'exécution de la boucle principale en secondes (man 2 times,
penser à diviser par sysconf(_SC_CLK_TCK). Pour utiliser _SC_CLK_TCK,
vous devrez inclure unistd.h).
Le temps qui nous intéresse est le temps total user+system.
-
Fichiers de tailles variables :
Écrire un programme gen.c qui prend en argument un entier n sur la ligne
de commande et affiche n fois le caractère . sur sa sortie standard.
Faire en sorte que gen imprime aussi son temps d'exécution sur stderr,
de la même façon pour le programme précédent.
-
Tampons de tailles variables :
Modifier le programme
copy1.c pour qu'il prenne en argument des entiers p et q et qu'il associe :
- un tampon de taille p sur stdin
- un tampon de taille q sur stdout
Pour la modification de la taille du tampon : man setvbuf et cours 1.
On conservera l'impression du temps d'exécution sur la sortie d'erreur.
Essayer plusieurs valeurs pour n, p, q dans l'exemple suivant:
./gen n | ./copy1 p q > logout
Exercice 3 - Le programme head
La commande
head n imprime les n premières lignes de
stdin sur
stdout.
Une ligne se termine par
'\n'.
- Réécrire cette commande avec un programme C ;
- Écrire un programme genline similaire à gen mais qui écrit
des lignes contenant "Bonjour" plutôt que des caractères. Par exemple, genline n
écrit n lignes contenantBonjour sur sa sortie standard.
-
Tester vos programmes avec des commandes du type :
./genline p | ./head q
On va maintenant observer l'impact de
head sur
genline :
- Modifier genline n pour qu'il écrive sur stderr :
ligne numero i, avec i de 1 à n, au fur et à mesure de la génération.
- Observer le comportement lorsque p>q et p<q. Est-ce que head q modifie le moment où se termine genline p ?
Pour pousser cette observation plus loin :
- Écrire un programme neverdie.c qui imprime indéfiniment la ligne
Bonjour (on l'arrête avec Ctrl-C).
- Tester ./neverdie | ./head 5
Exercice 4 - Le programme sort
La commande sort lit des lignes sur stdin, les range dans un tableau jusqu'à ce qu'il n'y ait plus rien à lire, puis écrit toutes les lignes lues sur stdout dans l'ordre du dictionnaire.
Réécrire cette commande en utilisant une bibliothèque de tri standard (
man qsort).
Il faut procéder comme suit:
Exercice 5 - Un programme pour filtrer les noms de fichier
Écrire une commande filter dirname filter qui parcourt le répertoire dirname et affiche les noms de fichier qui contiennent la chaîne de caractères filter. Pour cela vous pourrez utiliser la fonction strstr.
Exercice 6 - Le programme tail
La commande tail n f imprime les n dernières lignes du fichier f sur stdout.
C'est beaucoup plus difficile que pour head ou sort car il ne faut surtout
pas charger tout le fichier en mémoire. Utilisez fopen pour ouvrir le fichier.
On utilisera l'algorithme suivant. On charge un bloc à la fin du fichier avec fread,
et on y cherche
les sauts de ligne nécessaires (attention au cas de la dernière
ligne!). Si on ne les trouve pas tous (et si on n'a pas déjà lu tout le fichier),
on agrandit le buffer, et on recommence. Utilisez fseek et ftell pour
vous déplacer dans le fichier.
Peut-on utiliser la même méthode pour travailler avec stdin au lieu d'un
fichier f ?
Utiliser mmap() pour réécrire tail.
© Université de Marne-la-Vallée