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