Gestion des fichiers

Transcription

Gestion des fichiers
Gaudino, casier 5
version 1.4
Fichiers
Lycée Masséna
I.
P.C.S.I.834
Cours
On a souvent besoin d’un plus petit que soi d’utiliser un fichier auxiliaire, soit pour lire des données (par exemple les
résultats numériques d’une expérience, qu’on va traiter), soit pour inscrire des données (par exemple les résultats du
traitement numérique).
On se concentre ici sur l’OS Windows (qui est celui déployé au lycée). Le principe est analogue avec d’autres OS, avec
d’autres codes.
De manière générale, la plupart des OS permettent aujourd’hui d’utiliser des caractères accentués, des majuscules et
des minuscules, des noms longs. . . Toutefois, pour éviter les incompatibilités, il est conseillé :
1. de bannir les caractères exotiques : ne pas prendre de lettres accentués, pas d’espaces (mettre un tiret 8 à la
place), ne pas commencer par un chiffre ;
2. toujours écrire en minuscules vos noms de fichiers (car Windows n’est pas sensible à la casse, mais Linux l’est).
I.1.
chemin d’accès
– Arborescence des fichiers : les répertoires sont indiqués par un cadre plein, les fichiers par un cadre pointillé et un
fond gris.
C:
windows
tex
documents
python3
exemple1.py
exemple2.py
exercices
exemple3.py
pdf
exemple4.pdf
user
– Chemin absolu : c’est l’adresse complète du fichier, on peut ainsi l’obtenir de n’importe quel endroit de l’ordinateur :
C:\documents\python3\exemple1.py
– Chemin relatif : c’est l’adresse du fichier, par rapport à la position actuelle (le répertoire courant). Par exemple
pour le fichier précédent, et si la position actuelle est :
– à la racine : on tape C:\documents\python3\exemple1.py
– le répertoire C:\documents\python3 : on tape exemple1.py
– le répertoire C:\documents : on tape python3\exemple1.py
– le répertoire C:\documents\python3\exercices : on tape ..\exemple1.py (le .. permet de remonter d’un cran).
– le répertoire C:\documents\pdf : on tape ..\python3\exemple1.py (on remonte à documents par .., puis on
redescend vers python3).
– / ou \ ? La convention est différente entre Windows et Unix (et donc Linux et Mac-Os). Normalement, Python
adopte automatiquement la bonne convention : vous pouvez par exemple utiliser dans le code le caractère Unix
(/) et si votre script est utilisé sur une machine Windows, Python se débrouillera.
I.2.
droits d’accès
Suivant les systèmes, il existe divers types de droits :
1. droit en lecture ;
2. droit en écriture ;
1
3. droit en lecture-écriture ;
4. droit en exécution. . .
I.3.
en Python
On rappelle que le caractère qui permet de passer à la ligne dans une chaine est \n.
1. On accède à un fichier par la commande open, où on spécifie le mode d’accès : cet ensemble est mémorisé dans
une variable qu’on appelle dans cet exemple objet (pour la différencier du vrai fichier) :
objet = open('nom du fichier avec son extension', 'mode d'accès')
2.
3.
4.
5.
6.
7.
Le nom du fichier avec son extension suffit lorsque le fichier est dans le répertoire de travail (là où est enregistré
le script Python). Sinon, il faut mettre le chemin.
Pendant qu’il est ouvert, aucun autre programme ne peut y accéder dans le même mode (mais éventuellement
le peut dans un autre).
Le mode d’accès peut-être (on ne peut pas combiner les modes, mais il en existe d’autres - voir plus bas) pour
un fichier texte :
– 'r' (read) : lecture seule (mode par défaut, lorsqu’il n’est pas précisé). Provoque une erreur si le fichier n’existe
pas.
– 'w' (write) : écriture seule. Si le fichier n’existe pas déjà, il est crée. Si le fichier existe déjà, son contenu
est effacé.
– 'a' (append) : ouverture pour ajout. Si le fichier n’existe pas déjà, il est crée. Si le fichier existe déjà, son
contenu est conservé, et on écrit à la suite.
– Suivant les droits de l’utilisateur, on peut recevoir une erreur.
À la fin du travail, on ferme obligatoirement le fichier : objet.close(). Au pire, Python le ferme automatiquement (sinon, aucun autre programme ne pourrait plus y accéder). Mais il vaut mieux prendre l’habitude de le
faire proprement.
Qui plus est, dans le cas où on écrit dans un fichier, Python ne le fait pas toujours au moment où on le demande
(car c’est une opération assez longue car on doit accéder au disque dur, qui est lent : il attend d’avoir beaucoup
de choses à écrire). Fermer le fichier force Python à écrire les données (on peut aussi le faire avec la commande
flush).
Pour lire ou écrire dans un fichier, il faut comprendre comment il est parcouru. Python se positionne dans le
fichier à l’aide de ce qu’on appelle un curseur. À l’ouverture du fichier, il est au tout début. Il se déplace suivant
les actions entreprises :
– par exemple si on lit tout le fichier, il sera à la fin du fichier après cette action. Si on demande alors par
exemple l’écriture d’une nouvelle donnée, elle le sera à la fin.
– par exemple si on lit trois caractères, il sera sur le quatrième caractère après cette action. Si on demande alors
par exemple l’écriture d’une nouvelle donnée, elle le sera là (et écrasera les caractères précédents, ou suivant
la manière les décalera).
– on peut évidemment déplacer le curseur comme bon nous semble, avec les commandes adéquates. Néanmoins,
comme nous ne travaillerons que sur des petits fichiers, ce n’est pas ce que nous ferons.
Pour lire un fichier, on dispose de (entre autres) :
(a) la méthode read, qui lit l’intégralité d’un coup : on obtient une unique chaîne de caractères (qui contiendra
probablement le caractère \n à chaque saut de ligne) : objet.read() ;
(b) la méthode readlines, qui lit l’intégralité, mais en découpant ligne par ligne : on obtient une liste de chaînes
de caractères (avec les \n donc) objet.readlines().
On peut évidemment alors faire une boucle sur cette liste.
Ne pas oublier le s ! La méthode objet.readline() existe, elle ne lit qu’une seule ligne (et déplace le
curseur).
(c) Ce qui précède (objet.readlines()) est en fait à réserver aux fichiers courts.
Pour écrire dans un fichier, on dispose de :
(a) la méthode write, qui écrit la chaîne de caractères donnée : objet.write(chaine). Le caractère '\n' sera
traité comme un retour à la ligne ;
(b) la méthode writelines, qui écrit une liste de chaînes de caractères en les concaténant :
objet.writelines(liste de chaines). Attention, on n’a pas automatiquement de retour à la ligne pour
chaque élément de la liste : pour l’avoir, il faut un caractère '\n'.
Dans tous les cas, on ne lit ou n’écrit que des chaines de caractères (ou au pire des listes de chaines de caractères)
puisqu’on vient de présenter le mode texte. Il faudra donc systématiquement convertir les données, avec les
commandes str() ; int() ; float(). . .
2
8. Il existe une autre manière de faire : ouvrir, lire et écrire au format binaire. Il n’y a alors aucun besoin de
conversion. Mais seul quelqu’un qui sait exactement ce que contient le fichier pourra le réutiliser (un éditeur de
texte ne permettra pas de le lire).
C’est en fait la méthode à utiliser en sciences, pour des données numériques. En pratique, on passe sans difficulté
au mode binaire lorsqu’on a compris le mode texte. On se contentera donc ici de la première manière.
I.4.
split et strip
Deux commandes puissantes qui nous serviront :
1. méthode split : quand une chaine représentent plusieurs informations, séparées toujours par le même symbole,
la commande split permet de la tranformer en une liste de ses sous-chaines. Par exemple si on a la chaine
chaine = 'info1 ; info2 ; info3' où les informations sont séparées par des points virgules, alors la commande chaine.split(';') donnera la liste ['info1 ',' info2 ',' info3'] (attention aux espaces dans cet
exemple).
À noter que chaine.split() (sans rien dans les parenthèses) sera compris par Python comme un split avec le
caractère espace (découpage habituel d’une phrase en mots).
2. méthode strip : la méthode rstrip supprime les espaces et caractères d’échappement (comme \n ou \t, la
tabulation) à la fin d’une chaine (r = right), la méthode lstrip les supprime au début (l = left), la méthode
strip supprime les deux. Par exemple 'essai \n'.rstrip() donne 'essai'.
3. Les deux méthodes peuvent s’enchainer : par exemple pour supprimer \n à la fin d’une chaine, puis séparer en
mots (avec le séparateur virgule), faire dans cet ordre chaine.rstrip().split(',')
II.
Exercices
On pourra ouvrir les fichiers avec un éditeur de texte (notepad au pire, mais notepad++ est bien plus adapté) pour
les visualiser. Les éditeurs intelligents (comme notepad++ par exemple) permettent de visualiser le caractère de fin
de ligne (pas notepad).
1. Expérimenter les deux fonctions de lecture sur le fichier nom.txt fourni. Attention à deux points :
– quand on affiche une chaine de caractère (avec un print) qui contient \n, Python saute à la ligne au lieu
d’afficher le \n ;
– après une première lecture du fichier, Python place son curseur à la fin du fichier. Si on redemande une lecture,
il lit à partir de cette position (et ne trouve donc rien).
Quand on veut exploiter plusieurs informations, il faut donc lire le fichier une bonne fois pour toutes, enregistrer
cette information dans une variable, (fermer le fichier, c’est plus propre), et exploiter cette variable (et pas
relire le fichier à chaque fois).
Ce phénomène est identique en écriture : il écrit à la position du curseur (en général il ajoute des caractères
à la fin du fichier).
2. Écrire une fonction qui renvoie le nombre de lignes d’un fichier. Tester cela sur le fichier nom.txt fourni (on doit
trouver 10).
3. En utilisant le fichier nom.txt fourni, et qui présente les noms d’une classe (fictive) ligne par ligne, fabriquer la
liste des élèves de la classe.
Le caractère \n peut nous embéter.
4. En utilisant le fichier prenom.txt fourni, et qui présente les prénoms de la classe ligne par ligne (dans le même
ordre), fabriquer la liste des élèves de la classe, sous la forme [”nom prenom 1”, ”nom prenom 2”, . . . ] (attention
à l’espace).
Pour vous permettre de vérifier, les noms et les prénoms ont la même initiale, choisie dans l’ordre alphabétique
(Babbage Bernard, . . .) et il y a 10 élèves.
5. Fabriquer un nouveau fichier stupide.txt qui présentera l’information capitale suivante : ligne par ligne, on
aura le nom, puis le prénom, puis le nombre de caractères du prénom de chaque élève.
Les trois informations seront séparés d’une virgule (pas besoin de laisser d’espace).
Ce format : sur chaque ligne, des informations séparées par des virgules (ou par un autre caractère
choisi par convention) est appelé CSV pour comma-separated values. C’est le format de base utilisé
par les tableurs (Calc, Excel par exemple). L’extension de fichier est alors .csv (qu’il est préférable
d’écrire en minuscules). Il est en pratique très enrichi pour ajouter des éléments de mise en page
(couleur du texte, . . .) : on obtient alors les formats xls, xlsx, ods (que nous ne manipulerons pas).
CSV peut être lu et enregistré directement par ces tableurs.
3
6. En utilisant le fichier moyenne1.csv fourni, et qui représente, au format CSV, le tableau de la classe suivi des
notes au DS (à vous de trouver combien), fabriquer un fichier bulletin.csv au format CSV qui présente le
tableau des moyennes.
Dans ce premier exemple, tous les élèves ont le même nombre de notes. Attention en revanche, le tableau fourni
commence par son en-tête (nom,prenom,note1,note2,. . .). bulletin.csv devra aussi avoir un en-tête (nom,
prenom, moyenne).
On fera une fonction moyenne, et on pourra commencer par faire une liste (ou un n-uplet) avant de faire le fichier
[oui, je sais, vous avez commencé la question sans lire jusqu’au bout].
7. Question optionnelle : Même question avec le fichier moyenne2.csv fourni : tous les élèves n’ont pas le même
nombre de DS, il y a eu des absents. Néanmoins, le tableau des notes est rempli sans trou (les notes sont mises
bout-à-bout).
C’est la fonction moyenne qui doit être modifiée, probablement.
8. Question optionnelle : Même question avec le fichier moyenne3.csv fourni : ce sont les mêmes notes que
moyenne2.csv, mais il y a des trous (les notes ne sont pas mises bout-à-bout, la case est vide pour une absence). Les moyennes doivent être inchangées.
9. Question optionnelle : fabriquer l’analogue de la méthode split et de la méthode strip (dans la version : suppression
seulement des espaces finaux éventuels par exemple) sous forme de fonction.
10. Quelques petits exercices d’administration de réseau. Python est très puissant, vous pouvez en deux lignes écraser
définitivement le contenu du disque dur, ou attaquer un site Internet distant. Pour éviter de recevoir la visite de
la Police au lycée, nous allons nous limiter à travailler sur notre session locale (l’intérêt va être limité du coup).
(a) Fabriquer (pas grâce à Python, mais avec l’explorateur Windows) deux sous-répertoires du répertoire de
travail, rep1 et rep2. Copier trois fichiers textes distincts dans rep1 (nom.txt, prenom.txt, stupide.txt par
exemple).
(b) Taper une fonction Python qui prend en arguments deux chaines (qui seront en fait des noms de fichiers),
et qui fabrique une copie pure du premier dans le deuxième (le deuxième sera ainsi crée).
Copier avec cette fonction nom.txt dans le deuxième répertoire (en le renommant nom2.txt).
(c) En tapant à la main la liste des fichiers de rep1 dans votre programme, fabriquer une fonction qui prend
un argument (qui sera le nom du répertoire cible de la copie), et qui copie tous les fichiers de rep1 vers
cette cible (en ajoutant le suffixe 2 au nom de fichier).
Appliquer cette fonction pour tout copier dans rep2 (la première version de nom2.txt sera donc écrasée).
(d) Récupérer la liste des fichiers de rep1 automatiquement est très facile, comme fabriquer rep1 et rep2, mais
on ne vous donne pas la manière de le faire : il faut donc le faire à la main, alors qu’un ingénieur réseau le
ferait avec ces commandes.
4
Arborescence des fichiers : les répertoires sont indiqués par un cadre plein, les fichiers
par un cadre pointillé et un fond gris.
C:
windows
tex
documents
python3
exemple1.py
exemple2.py
exercices
exemple3.py
pdf
exemple4.pdf
user
5