Vous êtes sur la page 1sur 7

I05 Fichiers : lecture et écriture

PCSI 2017 – 2018

Motivation : Lorsque les calculs à effectuer prennent un temps important, on veut pouvoir sauvegarder les
résultats de façon durable (même après avoir éteint l’ordinateur). Il arrive aussi que l’on souhaite traiter des
données en provenance d’un autre programme (par exemple une carte d’acquisition en sciences physiques).
Il faut donc être capable depuis python de lire des fichiers sur le disque dur et d’y écrire des données.

I Droits d’accès
Comme cela a été vu au chapitre I00 , c’est le système d’exploitation qui gère les accès au disque dur
pour s’assurer que différents programmes n’exécutent pas des opérations différentes sur un fichier au
même moment. Il convient donc de respecter l’ordre suivant :
1. demander l’autorisation au système d’exploitation d’accéder à un fichier. Lui préciser ce que
l’on compte faire (écrire, lire. . .),
2. écrire les différentes opérations que l’on souhaite effectuer sur le fichier,
3. fermer le fichier , c’est-à-dire indiquer au système d’exploitation que l’on a fini d’utiliser le
fichier.

Remarques :
• Le système d’exploitation n’accorde pas nécessairement l’autorisation d’accéder à
un fichier. Il gère en général plusieurs utilisateurs chacun ayant des droits différents. Par exemple,
Pierre a le droit d’accéder à son dossier personnel en lecture et en écriture. Mais Paul n’a pas accès
aux dossiers de Pierre. S’il tente d’y accéder, le système d’exploitation doit lui refuser l’accès au
fichier. Pierre peut assouplir cette règle en autorisant Paul à lire ses fichiers auquel cas Paul pourra
y accéder en lecture uniquement. Pierre peut aussi donner les droits en écriture.
• La dernière étape est très importante. En effet, tant que l’on ne l’a pas effectuée, on ne
sait pas si le système d’exploitation a écrit les données. L’écriture sur le disque étant une
opération couteuse en ressource, le système d’exploitation choisit lui même quand l’effectuer. De
même, il peut refuser l’accès au fichier aux autres applications si celui-ci n’est pas fermé cor-
rectement. (message d’erreur typique : Le fichier est ouvert dans pythonw.exe,
fermer le fichier et réessayer)
On retiendra la bonne pratique suivante :
• Lorsque l’on demande l’accès à une ressource (mémoire, accès fichier, accès périphérique), on
libère l’accès à la ressource le plus rapidement possible pour ne pas oublier de le faire et pour ne
pas bloquer la ressource.

Dans l’idéal, il faut s’assurer que l’on libère l’accès à la ressource seulement s’il a été accordé et même si
le programme « plante ». Ce point sera évoqué en fin de chapitre.

II En python
1. Accès et fermeture du fichier
Pour ouvrir un fichier, on utilise la fonction open de python. Comme souvent, il convient de regarder
l’aide de la fonction en faisant help(open) (ou en cherchant sur internet pour avoir une présentation plus
lisible).

1
I05 Fichiers : lecture et écriture

Le prototype de la fonction est :


open(file, mode=’r’, buffering=-1, encoding=None,
errors=None, newline=None, closefd=True, opener=None) -> file object
Cela signifie :
• la fonction open prend un argument obligatoire ,
• 7 arguments optionnels avec des valeurs par défaut,
• et renvoie un objet de type file.
La documentation nous dit que l’argument obligatoire est le nom du fichier que l’on souhaite ou-
vrir (une chaine de caractères donc). L’argument optionnel mode indique la manière dont on
souhaite ouvrir le fichier , il existe de nombreuses façons mais on retiendra essentiellement :
• mode="r" : ouvre le fichier en mode lecture (read) , on ne peut donc pas écrire,
• mode="a" : ouvre le fichier en mode ajout , c’est à dire que le texte sera inséré à la fin du fichier,
• mode="w+" : crée le fichier s’il n’existe pas et l’efface s’il existe, le fichier est ouvert en
écriture. (Attention, aucune confirmation n’est demandée avant d’effacer le fichier, soyez prudent).
Comme tout les objets en python, un objet de type file a des attributs et des méthodes. Une méthode
d’un objet s’appelle de la façon suivante : objet.nom_de_la_methode(arguments). Par exemple
ici, notre objet fichier dispose d’une méthode close qui ne prend pas d’argument. On l’appelle donc
de la façon suivante fichier.close(). Cette méthode indique au système d’exploitation que
l’on a fini d’utiliser le fichier. Pour chaque fonction open, il faut un appel à close pour libérer les
ressources.
Exemple :
1 fichier=open("demonstration.txt","w+")#on crée le fichier ou on l’
efface
2 #open renvoie un objet de type fichier qui dispose de méthodes
3 #si tout s’est bien passé, le fichier est ouvert et peut être utilisé
4 fichier.close()

2. Écriture
Pour écrire dans un fichier, il faut ouvrir un fichier en mode écriture : mode="w+" par exemple. On
peut ensuite écrire dans le fichier via un appel à la méthode write. Cette méthode prend comme argument
une chaine de caractère et l’écrit dans le fichier.
Exemple :
1 fichier=open("demonstration.txt","w+")#on crée le fichier ou on l’
efface
2 fichier.write("x\tx**2\n")
3 f o r i i n range(10):
4 fichier.write( s t r (i)+"\t" + s t r (i**2) +"\n")
5 fichier.close()
Que fait ce morceau de programme ? Ouvre en écriture un nouveau fichier ou efface si existe déjà, écrit sur
une ligne x et x**2 puis donne les nombres et leur carré entre 0 et 9 en allant à la ligne.
Remarques :
• la méthode write ne peut prendre que du texte comme argument. Pour écrire des nombres,
il faut d’abord les convertir en chaine de caractères , par exemple en appelant la fonction
str,
• il est nécessaire de faire toute la mise en forme à la main. On peut par exemple introduire
des retours à la ligne grâce au caractère "\n" et des tabulations ( "\t" ) ,

PCSI Page 2/??


I05 Fichiers : lecture et écriture

• tant que l’on n’a pas appelé la méthode close, on ne sait pas si le texte est écrit ou pas . Ceci
explique qu’il faut toujours bien « éjecter » (unmount) une clé USB avant de la retirer. démo

3. Lecture
Pour lire, il faut utiliser un mode lecture, par exemple mode="r" . On peut ensuite lire le contenu du
fichier à l’aide de plusieurs méthodes :
• la méthode readline lit une ligne et renvoie une chaine de caractère, et place le curseur au
début de la ligne suivante (le curseur étant placé au début du fichier lors de son ouverture). On peut
ainsi avec des appels successifs à readline parcourir tout le fichier,
• la méthode readlines permet de lire tout le fichier depuis la position actuelle du curseur jus-
qu’à la fin du fichier et renvoie une liste de chaine de caractère, chaque élément correspondant
à une ligne.
Exemple :
1 fichier=open("demonstration.txt","r")#on ouvre en lecture
2 a=fichier.readline()#lit une ligne
3 b=fichier.readlines()#lit toutes les lignes et retourne une liste de
chaine de caractère
4 fichier.close()
5 p r i n t (a)
6 p r i n t (b)

Remarques :
• Lors de la lecture d’une ou de plusieurs ligne, le caractère "\n" est lui aussi lu, il faut en tenir
compte par la suite.
• Tout ce qui est lu est considéré comme une chaine de caractère (comme avec input) : pour
pouvoir lire des nombres, il faut donc faire explicitement la conversion vers un nombre de
la même façon qu’avec input en utilisant les fonction int et float.

4. Chemin
Le fichier considéré n’est pas nécessairement dans le même répertoire que le programme qui est exécuté,
il faut dans ce cas indiquer au programme dans quel dossier trouver le fichier, cela peut se faire de deux
façons :

En indiquant le chemin relatif : c’est-à-dire par rapport au dossier où s’exécute le programme. Par
exemple :
• f=open(’notes/test.txt’,’w+’) Ouvrira ou créera un fichier test.txt dans le sous-
dossier appelé notes,
• f=open(’../test2.txt’,’w+’) Ouvrira ou créera un fichier test2.txt dans le dossier
parent.

En indiquant le chemin absolu : c’est-à-dire par rapport au lecteur qui contient le dossier, indépendam-
ment de la position du programme.
Par exemple C:/Programmes/scilab/

PCSI Page 3/??


I05 Fichiers : lecture et écriture

Dossier où est exécuté


le programme Dans l’exemple ci-contre, le pro-
Racine (C:/ ; home/ ...) gramme s’exécute dans le dossier
Dossier_parent ../ C:/Dossier_parent/Dossier_courant/.
Pour accéder à un fichier dans le dossier
travail
sauvegarde, on a trois possibilités.
Dossier_courant
./sauvegarde/ • ./sauvegarde/fichier.txt
sauvegarde ou
• sauvegarde/fichier.txt
sauvegarde/
donnees qui sont des chemins relatifs (par rapport à la position
perso ../perso/ du programme), ou alors avec un chemin absolu :

• C:/Dossier_parent/Dossier_courant/sauvegarde/fichier.txt
Remarque : Les deux méthodes ont leurs avantages et leurs inconvénients, avant de choisir l’une ou l’autre
il faut s’interroger sur le comportement souhaité du programme lorsqu’on le déplace à un autre endroit.

5. Mode binaire
Pour le moment, nous n’avons parlé que d’écrire et de lire en mode texte. Il existe un autre mode appelé
binaire. Ce mode permet d’écrire directement sur le disque dur les données telles qu’elles sont en mémoire
(donc sous forme de 0 et de 1 codé de la façon vue au chapitre 1). Il faut pour cela rajouter un b dans le
mode d’ouverture, par exemple mode="wb+".

Avantages :
• Ce mode est en général beaucoup plus rapide puisqu’il n’est pas nécessaire de convertir en texte.
De plus, les fichiers peuvent être plus compact . Ce mode d’écriture est donc intéressant lorsque
le volume de donnés est très important (centaine de Mo).
• Les fichiers ne sont pas facilement lisibles (si on souhaite garder secret ce qui est à l’intérieur),
il faut savoir exactement comment le fichier a été écrit pour pouvoir le lire.

Inconvénients :
• Les fichiers ne sont pas facilement lisible (si on souhaite regarder facilement ce qui est à l’intérieur)
• En python, il est difficile d’utiliser ce mode soi-même et il vaut mieux avoir recourt à des modules.

6. Encodage
Nous avons vu dans le chapitre I04 que pour représenter des chaines de caractères on utilise une « table de
conversion ». Toutefois, pendant longtemps il n’y a pas eu de standard et donc différents systèmes ont été
établis. C’est ce qui fait que les lettres accentuées sont souvent mal lues lorsque vous changer de système
d’exploitation.
Dans python, si vous ne savez pas quoi mettre, ne remplissez pas cet argument optionnel et python choisira
un encodage adapté à votre système d’exploitation.
Si vous pouvez, utilisez l’utf-8 qui permet d’encoder à peu près tout les caractères que vous connaissez
et bien d’autres encore. C’est en particulier utile lorsque vous travaillez à plusieurs sur un fichier pour que
tout le monde voit le fichier de la même façon. (encoding = "utf8" dans python) démo

III Manipulation de chaine de caractères


Nous avons vu comment lire le texte, mais il n’est pas encore directement exploitable : en effet, les lignes
lues sont de la forme "9\ t81\ n" alors que les informations pertinente sont 9 et 81. Il faut donc mani-
puler les chaines de caractères pour extraire cette information.

PCSI Page 4/??


I05 Fichiers : lecture et écriture

La méthode strip : Les chaines de caractères disposent d’une méthode qui permet de retirer les es-
paces au début et à la fin de la chaine de caractère ainsi que le retour à la ligne. moyen mnémotechnique :
strip-tease, enlève tout ce qui est inutile
1 >>> " 9\t81 \n".strip()#espaces rajoutés pour l’exemple
2 ’9\t81’

La méthode split : Les chaines de caractères disposent d’une méthode qui permet de décomposer une
chaine de caractères en une liste de plus petites chaines , le découpage étant fait lorsqu’un mot est rencontré.
Ce mot doit être passé en argument de la méthode. Par exemple :
1 >>> "9\t81\t32\t25".split("\t")
2 [’9’, ’81’, ’32’, ’25’]
3 >>> "la physique et les maths et la chimie et les SII".split(" et ")
4 [’la physique’, ’les maths’, ’la chimie’, ’les SII’]

Conversion en entier ou en flottant : De même que pour input(), si on veut manipuler des nombres
entiers ou flottants, il faut ensuite utiliser les fonctions int et float.
Voici un exemple complet permettant de lire le fichier écrit au début du cours :
1 fichier=open("demonstration.txt","r")#on ouvre en lecture
2 tableau1=[]#Initialisation des listes
3 tableau2=[]
4 i=0 #compteur
5 f o r L i n fichier:
6 temp=L.strip().split("\t")
7 i f i==0: # on traite différemment la première ligne
8 tableau1+=[temp[0]]#car elle contient du texte
9 tableau2+=[temp[1]]#et non pas des nombres
10 else:
11 tableau1+=[ i n t (temp[0])]
12 tableau2+=[ i n t (temp[1])]
13 i+=1 #incrementation du compteur
14 fichier.close()
15 p r i n t (tableau1)
16 p r i n t (tableau2)
Le résultat du programme est :
[’x’, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[’x**2’, 0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Remarques :
• Les nombres ne sont plus entre ’ ’, ce qui indique qu’ils sont bien interprétés comme des nombres
et non pas comme des chaines de caractères.
• Écrire et lire les fichiers de cette façon est fastidieux, on préfèrera donc utiliser des modules qui le
font « à notre place » pour gagner du temps.

IV Module de numpy
La bibliothèque numpy que nous utiliserons beaucoup par la suite dispose d’une fonction loadtxt qui réalise
tout cela. Après avoir importé la bibliothèque, il suffit d’une commande :

PCSI Page 5/??


I05 Fichiers : lecture et écriture

loadtxt("demonstration.txt",skiprows=1)
pour réaliser l’équivalent de tout le programme précédent. On voit donc ici l’intérêt d’utiliser des biblio-
thèques pour programmer de façon plus efficace (et généralement plus sure puisque les bibliothèques sont
testées par de nombreux utilisateurs).

V Gestion des erreurs


L’écriture et la lecture dans des fichiers sont des opérations susceptibles de générer des erreurs même si le
programme a été bien conçu. Il peut donc être utile de gérer les erreurs. Le détail de ce paragraphe n’est pas
à connaitre.
Python permet la gestion des erreurs à l’aide de quelques mots clés :
1 try:
2 #Morceau de code dont on soupçonne qu’il peut être source d’erreur
3 except nom_de_l_erreur:
4 #que faire si l’erreur nom_de_l_erreur se produit
5 else:
6 #que faire si l’erreur ne s’est pas produite
7 finally:
8 #à faire dans tout les cas, qu’il y ait une erreur ou pas.
Dans notre cas, on veut ouvrir le fichier (opération qui peut échouer), puis écrire dedans (opération qui peut
échouer) puis fermer le fichier si celui-ci avait été bien ouvert.
Voici un exemple de code qui peut réaliser cela :
1 try:
2 fichier=open("musique.txt","w+") #cette manoeuvre peut échouer : on
la met dans un bloc try
3 except IOError:#en cas d’erreur
4 p r i n t ("Erreur lors de l’ouverture du fichier")
5 else:#si l’ouverture du fichier s’est bien passée
6 try:
7 fichier.write(2)#Ceci va planter car ce n’est pas une chaine
8 except (TypeError, IOError):
9 p r i n t ("Erreur lors de l’écriture dans le fichier")
10 f i n a l l y :#bloc exécuté dans tout les cas
11 fichier.close()#le fichier sera malgré tout fermé
Cette manière de faire est contraignante pour le programmeur, mais permet de faire des programmes fiables.
Dans le cadre des TP de cette année, nous ne le feront pas pour un soucis de simplicité, mais il faut retenir
que pour pouvoir écrire des programmes fiables il faut penser à gérer les erreurs qui peuvent apparaitre.

PCSI Page 6/??


I05 Fichiers : lecture et écriture

Table des matières

PCSI Lycée Poincaré

Vous aimerez peut-être aussi