3 cnthole : comptage de fichiers creux
L'utilisation des fichiers Ă accĂšs direct permet le positionnement du
curseur (position courante) dans le fichier au delĂ de la fin du
fichier. Le « trou » laissé au delà de l'ancienne fin de fichier par
ce déplacement contenant exclusivement des zéros. L'implémentation
habituelle est de ne pas écrire ces zéros sur le disque, on parle de
« fichiers creux ».
Plus précisément les fichiers sont alloués sur le disque sous la forme
d'une suite de blocs de caractĂšres. La taille BLKSIZE de
ces blocs est donnée par le champ st_blksize de la structure
struct stat retournée par les appels stat(),
lstat(), et fstat(). Pour chaque bloc, l'adresse du
premier octet est un multiple de BLKSIZE. Généralement, on
évite d'allouer les bloc plein de zéros, c'est-à -dire les blocs qui
contiennent BLKSIZE octets nuls. Dans la suite, on
appellera « trou » un bloc plein de zéros non alloué.
On désire écrire une commande cnthole :
cnthole filename...
permettant de connaßtre combien de blocs seraient gagnés si les
fichiers désignés par les arguments étaient constitués d'autant de
trous que possible.
Dans ses grandes lignes, la commande cnthole consiste, pour
chacun des fichiers de la ligne de commande, Ă
-
récupérer la taille BLKSIZE qui lui est propre ;
- lire le fichier par blocs de BLKSIZE octets ;
- pour chaque bloc, si ce bloc est plein de zéros, compter un
bloc gagné potentiel ;
- afficher sur la sortie standard le nombre de blocs gagnés
potentiels.
Cette commande sera implantée par des appels successifs à la fonction
static int cnt_hole(int fd);
retournant le nombre de blocs pouvant ĂȘtre gagnĂ©s pour le fichier
correspondant au descripteur fd. Cette fonction retourne -1
en cas d'erreur.
On fournit la fonction utilitaire suivante :
int bnull(const void *b, size_t len);
qui retourne vrai si et seulement si les len octets Ă partir de
l'adresse b sont nuls.
Exercice 5
Donnez les déclarations et le code du début de la fonction
cnt_hole() consistant en l'initialisation d'une variable
BLKSIZE.
Exercice 6
Donnez le code de la boucle principale de la fonction
cnt_hole() itérant sur les lectures du fichier
source pour compter les blocs de zéros.
Exercice 7
Donnez le code de la fonction main() de la commande
cnthole itérant sur les paramÚtres de la ligne de
commande et réalisant l'ouverture du fichier, l'appel
Ă cnt_hole(), la fermeture du fichier et l'affichage du
résultat.
Exercice 8
La commande cnthole proposée ne calcule pas combien de
blocs pourraient ĂȘtre gagnĂ©s pour un fichier, mais plus
précisément combien de blocs seraient gagnés entre les deux
implantations du fichier :
-
sans aucun trou ; et
- avec autant de trous que possible.
Ce qui est différent, en particulier pour un fichier comportant
déjà des trous.
Donnez les grandes lignes d'une commande qui fournirait
effectivement le nombre de blocs pouvant ĂȘtre gagnĂ©s pour un
fichier donné.